Ruby的yield
不像C#和Python中的迭代器.yield
本身实际上是一个非常简单的概念,一旦你了解了Ruby中块是如何工作的.
是的,块是一种函数式编程特性,尽管Ruby并不是一种合适的函数式语言.事实上,Ruby使用方法lambda
创建块对象,这是从Lisp创建匿名函数的语法中borrow 的,而匿名函数就是块.从计算机科学的Angular 来看,Ruby的块(和Lisp的lambda函数)是closures.在Ruby中,方法通常只占用一个块.(你可以通过更多,但这很尴尬.)
Ruby中的yield
关键字只是调用给定给方法的块的一种方式.这两个例子相当:
def with_log
output = yield # We're calling our block here with yield
puts "Returned value is #{output}"
end
def with_log(&stuff_to_do) # the & tells Ruby to convert into
# an object without calling lambda
output = stuff_to_do.call # We're explicitly calling the block here
puts "Returned value is #{output}"
end
在第一种情况下,我们只是假设有一个块,然后说调用它.在另一种情况下,Ruby将块包装在一个对象中,并将其作为参数传递.第一种方法效率更高,可读性更强,但实际上它们是一样的.你可以这样称呼其中一个:
with_log do
a = 5
other_num = gets.to_i
@my_var = a + other_num
end
它会打印最后被分配到@my_var
的值.(好吧,这是一个完全愚蠢的函数,但我想你明白了.)
块在Ruby中用于很多事情.在Java这样的语言中,几乎每个使用循环的地方,都会在Ruby中被占用块的方法所取代.例如
[1,2,3].each {|value| print value} # prints "123"
[1,2,3].map {|value| 2**value} # returns [2, 4, 8]
[1,2,3].reject {|value| value % 2 == 0} # returns [1, 3]
正如Andrew指出的,它也常用于打开文件和许多其他地方.基本上,只要有一个标准函数可以使用一些自定义逻辑(比如排序数组或处理文件),就可以使用块.还有其他用途,但这个答案已经太长了,我担心它会导致体质较弱的读者心脏病发作.希望这能消除这个话题上的困惑.