2009-11-16 66 views
149

什麼時候你會使用一個而不是另一個?Ruby中的proc和lambda有什麼區別?

+3

這裏是在同一個http://awaxman11.github.io/blog/2013/08/05/好的博客這是什麼是一個塊之間的差異/ – 2013-12-01 10:05:45

+1

這裏是更詳細的答案:http://stackoverflow.com/questions/626/when-to-use-lambda-when-to-use-proc-new – 2014-02-23 01:18:07

回答

228

區別在於它們處理參數的方式。使用proc {}Proc.new {}創建proc是等同的。但是,使用lambda {}會爲您提供一個檢查傳遞給它的參數數量的過程。從ri Kernel#lambda

相當於Proc.new,除了將得到的PROC對象檢查傳遞的參數的數目時調用。

一個例子:

p = Proc.new {|a, b| puts a**2+b**2 } # => #<Proc:[email protected](irb):1> 
p.call 1, 2 # => 5 
p.call 1 # => NoMethodError: undefined method `**' for nil:NilClass 
p.call 1, 2, 3 # => 5 
l = lambda {|a, b| puts a**2+b**2 } # => #<Proc:[email protected](irb):5 (lambda)> 
l.call 1, 2 # => 5 
l.call 1 # => ArgumentError: wrong number of arguments (1 for 2) 
l.call 1, 2, 3 # => ArgumentError: wrong number of arguments (3 for 2) 

另外,作爲肯所指出的,使用return拉姆達內部返回拉姆達的值,但是使用在從封閉塊一個進程返回return

lambda { return :foo }.call # => :foo 
return # => LocalJumpError: unexpected return 
Proc.new { return :foo }.call # => LocalJumpError: unexpected return 

因此,對於大多數快速使用它們是相同的,但如果你想自動嚴格論證檢查(也可有時調試幫助),或者如果你需要使用return語句返回的值proc,使用lambda

+4

準確地說lambda表達式非常像方法(檢查參數和返回意願從它們返回),而過程非常像塊(參數不檢查,返回將從包含的方法或lambda返回)? – pedz 2014-05-04 17:28:17

33

除了jtbandes的回答,return聲明在proclambda之間返回的內容也有所不同。

+0

好點。我將這添加到我的答案中。 – jtbandes 2009-11-16 04:57:45

+1

我也不能等待相當於「Ruby 3000」的東西來解決這個問題。這種區別太微妙了。 – tadman 2009-11-16 16:06:48

3

這有點微妙。它們都是創建閉包的方法,並且都返回Proc對象。實際上還有第三種方式 - Proc.new。不同之處在於它們的行爲方式,具體取決於您使用的是Ruby 1.8還是1.9(事實上,Ruby 1.9中還有另一種方法來創建它們)。在一般情況下,差異不是你需要擔心的。只有當你關心嚴格性時,纔會有所作爲。 When to use lambda, when to use Proc.new?涵蓋的差異相當不錯。

53

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 

[email protected]:~/tmp$ ruby a.rb 
before proc 
inside proc 

最後的方法puts,從來沒有執行,因爲當我們呼籲我們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 
[email protected]:~/tmp$ ruby a.rb 
before proc 
inside proc 
after proc 

在lambda中返回僅轉儲我們走出拉姆達本身和封閉的方法繼續執行的。控制流程關鍵字在proc和lambdas中處理的方式是它們之間的主要區別

+2

迄今爲止我見過的最精彩的解釋之一,我希望我可以+10它 – 2015-03-31 11:54:59

+0

非常感謝@Andrey Deineko – shoaib 2015-06-29 07:11:52

+2

輝煌的解釋@shoaib – 2015-08-09 04:24:33

-1

proc和lambda之間的區別在於proc只是代碼的副本,而參數依次被替換,而lambda是其他函數語言。(返回行爲,參數檢查)

0

一般來說,lambda比proc更直觀,因爲它們更類似於方法 。他們對arity非常嚴格,當你致電退貨時,他們只是退出 。出於這個原因,許多Rubyists使用lambdas作爲第一選擇,除非他們需要特定的特效。

大小:類別Proc的對象。像塊一樣,它們在 的範圍內進行評估。 Lambdas:也是類Proc的對象,但與常規過程略有不同。 它們是塊和特效的閉包,因此它們在 中被評估,它們被定義在其中。

創建PROC

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

創建拉姆達

b = lambda { |x| x 2}

相關問題