First Blood 来些血腥凶残暴力的!
这些经常在面试中被提问,内容很多。
从面试里单独拿出来,这东西相当于神器级别,必须谨慎对待。
yield是ruby中一个特殊的关键字,可以调用块方法(block),而block是ruby闭包的一种,
故将三者联系起来,yeild天生就是闭包的小跟班儿。感觉没必要单独讲,不然很割裂的赶脚。
** ruby 闭包** block,Proc,lambda
block 与 yield
block 是最常用到的,有两种形式,{}和do … end。
一般单行习惯用{},多行用do … end,当然这只是习惯。
1 | def test_yield |
还可以通过 Kernel#block_given? 方法询问当前的方法调用是否包含块。
1 | def test |
Proc对象
1 | plus = Proc.new { |x| x + 1 } |
这被称为延迟执行(Defferred Evaluation)。
通过**&操作符**,block 与 Proc对象可以相互转化。
1 | def math_one(a, b, &oper) |
那么这个&起了什么作用?
1 | def my_method(&code) |
&操作符的真正含义:Proc对象和块之间的切换符号。&code是一个块,code是一个Proc对象。
简单的去掉&操作符,我们就能再次得到一个Proc对象。
1 | def proc_to_block(greeting) |
lambda函数
lambda跟Proc就像两个双胞胎
1 | plus = lambda { |x| x + 1 } |
lambda跟Proc有两个最明显的区别:
- lambda检查参数的个数,Proc不会。
在Proc中,多余的参数被设为nil。但lambda中,Ruby会抛出一个ArgumentError错误。 - return不同。
lambda的return是返回值给方法,方法会继续执行。Proc的return会终止方法并返回得到的值。看了代码会一目了然。参考了不少资料,就是拼凑的起来的。1
2
3
4
5
6
7
8
9
10
11
12def proc_return
Proc.new { return "Proc.new"}.call
return "proc_return method finished"
end
def lambda_return
lambda { return "lambda" }.call
return "lambda_return method finished"
end
puts proc_return # => Proc.new
puts lambda_return # => lambda_return method finished