第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Ruby 的塊

塊是 Ruby 程序員最喜歡的東西之一。它是一項(xiàng)非常強(qiáng)大的功能,使我們能夠編寫非常靈活的代碼,擁有極高的可讀性,并且可以在各處使用。本章中我們會(huì)詳細(xì)為您講解塊的使用。

1. 什么是塊

Ruby 的塊(Block)的概念在其他語(yǔ)言中也被稱為閉包。本質(zhì)上,塊與方法是相同的,除了它沒有名稱并且不屬于對(duì)象。塊是一段接受參數(shù)并返回值的代碼并總是通過(guò)傳遞給方法來(lái)調(diào)用。

2. 如何創(chuàng)建一個(gè)塊

塊有兩種表達(dá)形式,一種是 do...end,用來(lái)包含多行代碼,另外一種是 {},只包含1行代碼。

實(shí)例:

5.times do
  puts "Hello, This is from inside of block."
end

#---- 輸出結(jié)果 ----
Hello, This is from inside of block.
Hello, This is from inside of block.
Hello, This is from inside of block.
Hello, This is from inside of block.
Hello, This is from inside of block.

再看另一種例子:

實(shí)例:

5.times { puts "Hello, This is from inside of block." }

#---- 輸出結(jié)果 ----
Hello, This is from inside of block.
Hello, This is from inside of block.
Hello, This is from inside of block.
Hello, This is from inside of block.
Hello, This is from inside of block.

解釋:這兩種語(yǔ)句完全相同,它們的含義均是向 5times 實(shí)例方法中傳遞了一個(gè)塊,而 times方法接收了塊,并執(zhí)行了里面的內(nèi)容。由此可見,可以簡(jiǎn)單的將整個(gè)塊理解成可以作為方法的一個(gè)特殊參數(shù)。

Tips:在 Ruby 社區(qū)中,慣例是塊只有單行的時(shí)候使用花括號(hào) {},每當(dāng)塊多于一行的時(shí)候,使用do..end。雖然花括號(hào)也可以接收多行參數(shù)。

3. 塊如何接收參數(shù)

塊經(jīng)常與哈希、數(shù)組結(jié)合成迭代器Iterators)來(lái)使用。這里我們給出了一個(gè)塊接收參數(shù)的例子。

實(shí)例:

[1, 2, 3, 4, 5].each do |number|
  puts "#{number} was passed to the block"
end

#---- 輸出結(jié)果 ----
1 was passed to the block
2 was passed to the block
3 was passed to the block
4 was passed to the block
5 was passed to the block
[1, 2, 3, 4, 5].each { |number| puts "#{number} was passed to the block" }
 
#---- 輸出結(jié)果 ----
1 was passed to the block
2 was passed to the block
3 was passed to the block
4 was passed to the block
5 was passed to the block

解釋:上面兩個(gè)例子是完全相同的,跟方法不同的是,number參數(shù)沒有使用括號(hào)(())括起來(lái),而是使用豎線(|)的形式列出。

在迭代器(Iterators)中,我們可以通過(guò)操作塊來(lái)改變返回值。

實(shí)例:

[1, 2, 3, 4, 5].collect { |number| number + 1 }

#---- 輸出結(jié)果 ----
[2, 3, 4, 5, 6]

解釋:它調(diào)用原始數(shù)組上的collect方法,該方法為每個(gè)元素調(diào)用給定的塊,并收集該塊返回的每個(gè)返回值。然后,通過(guò)方法collect返回一個(gè)新的數(shù)組。

4. 創(chuàng)建一個(gè)帶有塊方法

4.1 隱形參數(shù)形式

這種形式我們會(huì)在方法后面?zhèn)魅胍粋€(gè)塊,用yield來(lái)調(diào)用塊內(nèi)的方法:

實(shí)例:

def sayHello 
  yield                                  # 塊會(huì)在這里被調(diào)用
end
sayHello {puts 'Hello, This is a block'} # 傳入塊

#---- 輸出結(jié)果 ----
Hello, This is a block

它實(shí)際上和下面這個(gè)代碼是一致的:

def sayHello 
  puts 'Hello, This is a block'                      
end
sayHello

#---- 輸出結(jié)果 ----
Hello, This is a block

塊是可以多次調(diào)用的:

實(shí)例:

def sayHello 
  yield # 塊會(huì)在這里被調(diào)用
  yield # 塊會(huì)在這里第二次被調(diào)用
end
sayHello {puts 'Hello, This is a block'} # 傳入塊

#---- 輸出結(jié)果 ----
Hello, This is a block
Hello, This is a block

注意事項(xiàng):當(dāng)沒有塊傳入sayHello方法的時(shí)候,調(diào)用yield會(huì)拋出異常:

實(shí)例:

def sayHello 
  yield                        # 塊會(huì)在這里被調(diào)用
end
sayHello                       # 不傳入塊

#---- 輸出結(jié)果 ----
ruby.rb:2:in `sayHello': no block given (yield) (LocalJumpError)

所以,如果塊是一個(gè)可選項(xiàng),我們要使用block_given?方法,僅當(dāng)塊傳入的時(shí)候調(diào)用。

def sayHello 
  yield if block_given?        # 塊會(huì)在這里被調(diào)用
end
sayHello                       # 不傳入塊

# 不會(huì)拋出異常

4.2 顯式參數(shù)形式

當(dāng)我們顯示聲明塊參數(shù)的時(shí)候,要使用&來(lái)標(biāo)注哪個(gè)參數(shù)是塊(&后面的參數(shù)名稱是任意的。)

實(shí)例:

def sayHello &block
  block.call                             # 塊會(huì)在這里通過(guò)call來(lái)調(diào)用
end
sayHello {puts 'Hello, This is a block'} # 傳入塊

#---- 輸出結(jié)果 ----
Hello, This is a block

注意事項(xiàng):顯示聲明塊參數(shù)的時(shí)候,如果不傳入塊,block的值會(huì)成為nil,所以,這種時(shí)候如果塊是可選項(xiàng),我們可以通過(guò)增加判斷block來(lái)忽略塊調(diào)用部分代碼。

def sayHello &block
  block.call if block           # 塊未傳入時(shí)不會(huì)調(diào)用block.call
end
sayHello                        # 傳入塊

# 不會(huì)拋出異常

注意事項(xiàng):當(dāng)方法有多個(gè)參數(shù)的時(shí)候,block的參數(shù)一定要放到最后。

def sayHello name, &block
  ...
end

4.3 如何調(diào)用含有參數(shù)的代碼塊?

當(dāng)我們使用隱形參數(shù)的yield來(lái)調(diào)用含有參數(shù)的代碼塊的時(shí)候我們直接將參數(shù)傳入yield,類似方法的調(diào)用形式。同樣,我們定義塊的時(shí)候,也要設(shè)置接收這個(gè)參數(shù)。

def sayHello
  yield('Andrew')
end
sayHello { |name| puts "Hello, #{name}, This is block" }

#---- 輸出結(jié)果 ----
Hello, Andrew, This is block

當(dāng)我們使用顯式參數(shù)的時(shí)候,調(diào)用的形態(tài)基本一樣。

實(shí)例:

def sayHello &block
  block.call('Andrew')
end
sayHello { |name| puts "Hello, #{name}, This is block" }

#---- 輸出結(jié)果 ----
Hello, Andrew, This is block

Tips : block.arity 返回塊一共需要接收多少個(gè)參數(shù),block.call 用來(lái)調(diào)用這個(gè)塊。

5. 小結(jié)

本章節(jié)中我們了解了塊,知道了可以通過(guò){}創(chuàng)建單行的塊,也可以通過(guò)do...end創(chuàng)建多行的塊,我們?cè)趬K中可以使用|參數(shù)|的形式接收傳入?yún)?shù)。如果自己要定義帶有塊的方法的話,有隱形和顯式兩種執(zhí)行塊的方式,我們同樣還可以向塊中傳入?yún)?shù),形式和方法傳參是一致的。