【问题标题】:Are blocks passed as arguments?块是否作为参数传递?
【发布时间】:2013-05-29 17:49:37
【问题描述】:

我可以像这样向函数传递参数:

func 1, 2, 3

或者我可以使用如下括号:

func(1, 2, 3)

后来我了解了像 list.each 这样的函数,我通过(不确定这是否真的发生了)一个块来操作每个元素:

list.each {|x| puts x}

我假设这只是将块作为参数传递给 each 函数,但事实并非如此,因为:

list.each( {|x| puts x} )

不工作。

当我看到这一点时我意识到了这一点:

5.upto(9) {|x| puts x}

如果块只是一个参数,这根本没有意义。

这里发生了什么?您可以向我指出任何资源来帮助解释这一点,也许还有其他不立即显而易见的结构?

【问题讨论】:

  • 这是一种专门为将块传递给函数而创建的特殊语法。对于每个函数调用,您可以在常规参数列表之外传递一个块。该块仍附加到被调用函数上下文中的参数列表中。
  • @Matt - 既然你正在学习 Ruby,请查看:codecademy.com/tracks/ruby - 对于任何想要学习 ruby​​ 语言核心基础的人来说,这都是非常好的资源
  • @David,我就是这样! :)
  • @Matt pro 坚持下去!

标签: ruby syntax


【解决方案1】:

块确实有点特殊,但也可以用作参数。考虑这个函数:

def greet
  yield "Hello"
end

greet{ |greeting| puts "#{greeting} to you" }

你也可以这样写:

def greet(&block)
  block.call("Hello")
end

greet{ |greeting| puts "#{greeting} to you" }

# which is equivalent to:
my_proc = proc{ |greeting| puts "#{greeting}, nice to see you." }
greet(&my_proc)

最后,块是一种特殊形式的过程,具有特殊的语法,使它们更有用。但是你仍然可以访问 procs 并传递它们。

【讨论】:

  • +1。我要补充一点,有一些问题。块在技术上是 Proc 对象,与 lambda 对象相似但不完全相同。他们各自的行为与例如例如,splat 参数并不完全相同。 (诚​​然与 Ruby 错误有关,自从我上次使用 Ruby 进行大量工作以来,这些错误可能已经修复,但当时存在诸如此类的生动微妙之处。)另外,请注意,通过使用 &block 语法,您 显式在每次调用时创建一个 Proc 对象——即使没有传递任何块,由于创建过多的对象而导致代码变慢。
【解决方案2】:

方法可以只接受一个块,有点像一个特殊的参数。

def foo
  yield 123
end

foo { |x| puts x }
#=> 123

请注意该方法如何接受零参数,但仍接受块。这是因为这种将块挂在方法上的语法是一种特殊情况。传递给方法的任何块都可以使用 yield 关键字运行。你甚至可以通过block_given? 关键字询问是否传入了一个块。

如果你想在一个局部变量中捕获它,你可以用一些特殊的语法来做到这一点。

def foo(a, &block)
  block.call a
end

foo(123) { |x| puts x }
#=> 123

在这种情况下,您将显式捕获块参数,并在参数列表中使用 & 前缀。您现在拥有该块的变量,您可以发送call 消息以执行该变量。只要知道这必须出现在参数列表的末尾。

还要注意括号。 foo(123) { |x| puts x }。参数列表停止,括号关闭,附加块紧随其后。同样,因为这是语法中的一种特殊情况。

【讨论】:

  • 谢谢。你可以打电话给:def two_func_in(&func1, &func2) 吗?那个电话会是什么样子?编辑:您说“方法可以完全接受一个块”。这就是这个问题的答案吗?
  • def two_func_in(&func1, &func2) 不是有效的红宝石。一个方法只能附加一个块。但是还有其他方法可以将一些代码作为基本的简单参数传递。就像Proc 对象一样,虽然处理它的语法不同。
猜你喜欢
  • 2013-02-21
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-03
  • 1970-01-01
相关资源
最近更新 更多