透視Ruby 1.9的Lambda函數

來源:互聯網
上載者:User

Ruby的Block塊是它的關鍵特色之一,用塊能夠寫出簡明且高度可重用的演算法。即使沒有別的用處,它 至少消弱了人們對迴圈敬畏的態度。這個概念在其他語言和理論中還被稱為:

◆lambda函數

◆匿名函數

◆閉包(參見Java 7中lambda函數所使用的名稱)

這是個十分令人迷惑的詞彙,因為閉包這個詞彙還指對代碼範圍的捕獲。而塊則不需要捕獲這個作 用域——例如下面的代碼:

x = lambda {|x,y| x + y}

沒有使用自由變數(沒有綁定的變數;參數列表中正式聲明x和y),因此無須建立一個閉包。

塊在其他語言中有很多種多樣的表現形式,有的簡潔有的冗長。比如對Ruby影響深遠的LISP語言,所 使用的塊文法為:

(lambda (arg) "hello world")

對Ruby的設計產生影響的另一種語言Smalltalk,採用方括弧來簡潔地表達文法:

[arg| ^"hello world"]

Ruby中,塊的最方便也最常使用的文法是作為函數的參數。它允許簡單地在函數名後面添加一個用 do/end 或者花括弧{ / }包圍的代碼塊。例如:

5.times {|x| puts x}

這非常的方便,同時也產生了Builder這樣的習慣性用法。Builder可以通過嵌套的塊來很容易地建立 分層的資料結構。(提示:就在一月下旬InfoQ即將發表一篇詳細描述如何在Ruby中建立Builder的文章) 。

不過,還有一個問題:要傳遞一個以上的塊給函數或方法就沒那麼簡單了。它可以實現,但不能用這 麼短的文法,得使用Proc.new {} 或lambda {} 來建立塊。雖然還不至於恐怖,但這樣會使代碼冗長,而 且還引入了一些不受歡迎的詞彙把代碼搞得淩亂不堪。(注意:Proc.new {} 和 lambda {}也有些微妙的 不同,但本文不關注它們)。

在特定情況下可能有變通的方法。例如,如果一個API調用需要多個塊,輔助函數就會嵌入到類中,這 樣就產生了兩個作用:a) 輔助了塊 b) 帶有貌似具名引數的負作用:

find (predicate {|x,y| x < y}, predicate{|x,y| x > 20})

其中predicate函數僅僅是:

def predicate(&b) b end

它用來返回這個塊。不論這是否合適或者不依賴於特定情況。在這種情況下,下面的代碼——毋庸置 疑地——更能表達清楚,也能起到相同的作用。

find (lambda{|x,y| x < y}, lambda {|x,y| x > 20})

為什麼呢?因為lambda泄露了實現它的細節——若帶有一個塊參數,就不需要額外的關鍵詞。 predicate的解決方案對代碼做了註解,併產生了lambda。需要明確的是,這隻是變通的方法。

現在,Ruby 1.9引入了一個新的、更簡潔的文法來建立lambda函數:

 x = ->{puts "Hello Lambda"}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.