什么时候你会使用其中一种而不是另一种?


当前回答

proc和lambda之间的区别在于,proc只是一份代码的副本,参数被依次替换,而lambda则像其他语言一样是一个函数。(返回行为,参数检查)

其他回答

procs和lambdas之间的真正区别在于控制流关键字。我说的是return, raise, break, redo, retry等等——这些控制词。假设你在一个proc中有一个return语句。当你调用你的proc时,它不仅会把你从它里面转储出去,而且还会从封闭的方法中返回,例如:

def my_method
  puts "before proc"
  my_proc = Proc.new do
    puts "inside proc"
    return
  end
  my_proc.call
  puts "after proc"
end

my_method

shoaib@shoaib-ubuntu-vm:~/tmp$ ruby a.rb
before proc
inside proc

final函数放入方法中,从未执行过,因为当我们调用proc时,它的return函数将我们从方法中丢弃。然而,如果我们将proc转换为lambda,我们会得到以下结果:

def my_method
  puts "before proc"
  my_proc = lambda do
    puts "inside proc"
    return
  end
  my_proc.call
  puts "after proc"
end

my_method
shoaib@shoaib-ubuntu-vm:~/tmp$ ruby a.rb
before proc
inside proc
after proc

lambda内部的返回值只是将我们从lambda本身中转储出来,而封闭的方法继续执行。在procs和lambdas中处理控制流关键字的方式是它们之间的主要区别

只有两个主要的区别。

首先,lambda检查传递给它的参数数量,而proc则不检查。这意味着如果传递错误数量的参数,lambda将抛出一个错误,而proc将忽略意外的参数,并将nil分配给任何缺失的参数。 其次,当lambda返回时,它将控制权传递回调用方法;当一个进程返回时,它立即返回,而不返回到调用方法。

要了解这是如何工作的,请查看下面的代码。第一个方法调用一个proc;第二个调用lambda。

def batman_ironman_proc
  victor = Proc.new { return "Batman will win!" }
  victor.call
  "Iron Man will win!"
end

puts batman_ironman_proc # prints "Batman will win!"

def batman_ironman_lambda
  victor = lambda { return "Batman will win!" }
  victor.call
  "Iron Man will win!"
end

puts batman_ironman_lambda # prints "Iron Man will win!"

看看proc如何说“Batman will win!”,这是因为它立即返回,而不需要回到batman_ironman_proc方法。

然而,我们的lambda在被调用后返回到该方法中,因此该方法返回它计算的最后一个代码:“Iron Man will win!”

proc和lambda之间的区别在于,proc只是一份代码的副本,参数被依次替换,而lambda则像其他语言一样是一个函数。(返回行为,参数检查)

一般来说,lambda比procs更直观,因为它们 更类似于方法。他们对arity要求很严格,他们只是 当你调用return时退出。由于这个原因,许多ruby开发者使用lambdas作为 首选,除非他们需要procs的特定功能。

Procs: Proc类的对象。像块一样,它们在作用域中进行计算 它们被定义的地方。 Lambdas:同样是Proc类的对象,但与常规procs略有不同。 它们像block和procs一样是闭包,因此它们被求值 定义它们的范围。

创建过程

a = Proc.new { |x| x 2 }

创建λ

B = lambda {|x| x 2}

一篇关于ruby指南:blocks, procs和lambdas的有用文章

Procs从当前方法返回,而lambdas从lambda本身返回。 Procs不关心参数的正确数量,而lambdas则会引发异常。