ruby中的Proc和lambda

蔡源茂 | 创建:2018-05-17 | 最后更新:2018-05-20 | 877次阅读

1. Proc和lambda定义

Proc是一个可以将块实例化为类实例的类。 proc和lambda也能使块实例化,看下代码的执行结果

#ruby2.4.1
p = Proc.new {p 1}   #=> #<Proc:0xa04c7fc3>
p.call #=> 1

p = proc { p 1 }  #=> #<Proc:0xa04c7fc3)>
p.call #=> 1

p = lambda { p 1}  #=> #<Proc:0xa04c7fc3 (lambda)>
p.call #=> 1

p = -> { p 1}  #=> #<Proc:0xa04c7fc3 (lambda)>
p.call #=> 1

2.看下proc和lambda的区别

#ruby2.4.1
def test1()
  p = proc{return 1}
  p.call
  0
end
def test2()
  p = lambda{return 2}
  p.call
  0
end
p test1 #=>1
p test2 #=>0

结论1:proc 是向test1中插入了一段动态代码块,而lambda则更像是插入了一个方法定义。因此,proc跳出了test1,而lambda仅仅是跳出了lambda定义的匿名方法

#ruby 2.4.1
def test(&p)
  p.call 1,2

end
test(&proc{|i| p i}) #=> 1
test(&proc{|m,n| p (m + n)}) #=> 3
test(&lambda{|i| p i}) #=> in `block in <main>': wrong number of arguments (given 2, expected 1)

结论2:proc不检查参数个数,lambda检查参数个数

3. proc和lambda的特点

proc和lambad 并不能仅仅理解为,是向调用的地方插入了一段代码或者是一个匿名函数。而且是应该理解为绑定了定义时所在作用域的一段代码或者一个匿名函数

#ruby2.4.1
def test
  m = 1
  n = 2
  yield
end
m= 3
test(&proc{p m}) #=>3
test(&lambda{p m}) #=>3
test(&proc{p n}) #=>undefined local variable or method `n' for main:Object (NameError)
test(&lambda{p n}) #=>undefined local variable or method `n' for main:Object (NameError)

最后,来看一组功能相同的5行代码

#ruby2.4.1
p ["1","2"].map(&:to_i)                       #=>   [1,2]
p ["1","2"].map(&:to_i.to_proc)               #=>   [1,2]
p ["1","2"].map(&proc{|i| i.to_i})            #=>   [1,2]
p ["1","2"].map(&Proc.new {|i| i.to_i})       #=>   [1,2]
p ["1","2"].map{|i| i.to_i}                   #=>   [1,2]

注:&会触发.to_proc方法

参考链接:

  1. 聊聊 Ruby 中的 block, proc 和 lambda
  2. 浅谈ruby语言中的一些概念(lambda, proc, block)


共收到 0 条回复


评论:

忘记密码?
其他账号登录: QQ登录

回到顶部
到达底部