ruby中的&操作符,以及各種閉包、proc的調用研究

來源:互聯網
上載者:User
 
class Array  def iterate!(&code) #注意這裡用了&符號    self.each_with_index do |n,i|      self[i] = code.call(n)    end  endendarr = [1,2,3,4]arr.iterate! do |n|  n ** 2end #[1, 4, 9, 16]

  

今天讀代碼的時候,被這個&符號給蒙住了。ruby語言中時不時蹦出各種奇怪的符號,而且作用不明。還不好查得。

於是認真研究了一下。

&操作符的真正含義:proc對象和塊之間的切換符號。&code 這是一個塊, code 這是一個proc對象。簡單的去掉&操作符,我們就能再次得到一個Proc對象。

===================================================

呃,其實如果沒有上下文,完全說不清楚這段。還是看下面的例子吧,運行一趟就知道了。 

def math_by_anonymouse_block(a,b)    yield a,benddef math_by_proc(a,b,a_proc)    a_proc.call(a,b)enddef math_by_named_block(a,b,&namedblock)puts "math_by_proc a,b,namedblock"puts namedblock.class # &namedblock 是一個區塊,namedblock (去掉&)是一個proc,&操作符是個切換開關。puts math_by_proc a,b,namedblockputs "======="#lambdamylambda = lambda &namedblock    puts mylambda.class    puts math_by_anonymouse_block a,b,&mylambda#哈哈,下面這樣也可以puts "math_by_proc a,b,mylambda"puts math_by_proc a,b,mylambdaputs "======="#proc    myproc = proc &namedblock    puts myproc.class    puts math_by_anonymouse_block a,b,&myproc#哈哈,下面這樣也可以puts "math_by_proc a,b,myproc"puts math_by_proc a,b,myprocputs "======="    #puts &namedblock.class#區塊不能直接賦值給一個變數。但是可以通過方法來傳遞    #myblock = &namedblock   #運行不通    #puts myblock.class#所以我們用這種方式puts "math_by_anonymouse_block"puts math_by_anonymouse_block a,b,&namedblockputs "======="endmath_by_named_block(2,3) {|x,y| x*y}

 

運行結果:
---------- ruby run ----------math_by_proc a,b,namedblockProc6=======Proc6math_by_proc a,b,mylambda6=======Proc6math_by_proc a,b,myproc6=======math_by_anonymouse_block6=======輸出完成 (耗時 0 秒) - 正常終止

  

區塊就像是方法的額外匿名參數,任何方法在調用時,都可以在後面跟一個區塊。只不過如果這個方法中有yield語句,它就會調用區塊,如果沒有yield語句,就無視這個區塊。

比如:

def my_noyield  puts "leave me alone. no yield !"enddef my_yield            puts "I call you! come on"  yieldendmy_noyield { puts "I'm coming!"}my_yield { puts "I'm coming!"}

這是我們來定義一個帶&操作符參數的方法,這就等於把之前的匿名參數變成了一個 &變數名 的參數。這個參數是一個也必然必須是一個 區塊(不是proc,去掉&才是proc)

def my_third(&myproc)puts "I call you! come on"yieldendmy_third { puts "I'm coming!"}

這裡 &myproc 是個區塊,而myproc是個proc。對於proc,我們應該可以直接調用proc.call.

所以我們來試試第4個方法:不用yield,而在方法中直接call 這個proc

def my_fourth (&myproc)puts "I call you! come on"myproc.callendmy_fourth { puts "I'm coming!"}

其實 &就是個切換開關,加上這個開關,就可以在proc和block之間切換。proc/lambda 也是一個開關(這兩個是核心方法:Kernel#proc :Creates a new procedure object from the given block. Equivalent to Proc.new .)

def my_fivth (&myproc)puts "I call you! come on"#&&myproc.call  這個不行,不能反轉兩次?c_proc = proc &myprocc_proc.callendmy_fivth { puts "I'm coming!"}def my_sixth (&myproc)puts "I call you! come on"c_proc = lambda &myprocc_proc.callendmy_sixth { puts "I'm coming!"}

  

補充一個小結:

可調用對象,有以下幾種形式:塊,proc,lambda,方法。不同類的可調用對象有細微區別。

但仍然可以通過以下方法在它們之間轉換:包括Proc.new()方法,Methrod#to_proc()方法和&操作符。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.