| 赞 | 0 |
| VIP | |
| 好人卡 | |
| 积分 | 18 |
| 经验 | |
| 最后登录 | 2020-8-1 |
| 在线时间 | 2161 小时 |
酱油的
- 梦石
- 0
- 星屑
- 1840
- 在线时间
- 2161 小时
- 注册时间
- 2007-12-22
- 回帖
- 3216

|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
塊(block)
:甚麽是 Block ?
我們經常可以看到這樣類型的語句
|[1,2,3,4].map!{|i| i +=1 }
其中{ }所包括的部分就是塊(Block)
:Block 的實際意義是?
說起 block ,最先想到的自然是迭代器(Interator)。
|[1,2,3,4].map!{|i| i +=1 }
因此,很容易就把 Block 和迭代(Interation) 聯繫起來
當然這個本身沒有錯誤,但是實際上使用 Block 幷不止 Interator 一家
比如文檔路徑(Dir)當中就使用了 Block
|Dir.open("."){|dir| p dir.to_a}
先入爲主地,很容易認爲 Dir.open 語句也是一個 Interation
實際上無論如何,這個 p 語句都不會執行多於一次
而且 p Dir.open(".") 與 p dir 都會返回一個數值
那麽 這個 Block 在這裏的意義是甚麽呢?
我們首先理解一下 Block 的實現
|def testblock(val)
| yield val
|end
Block 的實現與 yield 語句密不可分。
除非方法當中含有 yield 語句,否則 Block 會被視作無效
當方法當中有 yield 語句的時候調用方法以及 Block:
|testblock("I am block"){|i| p i}
結果我們在屏幕看見了 "I am block" 的語句。
但是疑問的是,yield 這個語句是怎麽操作的呢?
事實勝於雄辯。再看看以下方法:
|def testblock(val)
| yield val
| yield val
|end
與上面不同的是這裏調用了兩個 yield 語句
然後我們調用這個語句
|testblock("I am block"){|i| p i.id}
屏幕上顯示了兩次的 8537244 (每個程序都不一樣,這裏只是參考值)
我們得知實例的 id 是惟一的。
p 出兩次同樣的 id 證明我們這兩個 i 是完全一樣的
那麽結論就是:我們調用了兩次同一個實例
這說明了甚麽呢?yield 語句是關鍵。
當我們調用 Block 的時候,系統會調用 yield 語句。
一個方法當中的 yield 語句决定了 {|instance| method }的執行次數
Block 當中的 instance 值是完全由方法當中的 yield 語句賦予
實際上執行的語句就差不多是這樣子
| val = "I am block"
| i = val
| p i.id
| i = val
| p i.id
如果我們把語句改寫爲這樣:
|def testblock(val)
| yield val
| yield 1
|end
那麽,我們看到的大概就是這樣的執行
| val = "I am block"
| i = val
| p i.id
| i = 1
| p i.id
每一次的 yield 語句都把 Block 內的 |instance|重新賦值,
然後執行後面的 method 方法。
由此可見 Block 的執行次數只跟跟方法內的 yield 語句多少産生關係
即使帶有 Block,程序也可能只執行「一次」。
這個方法被稱爲 callback
我們利用 yield 語句截取不同的值,
返回給 Block 當中的 instance 實例
然後再調用 method 語句(這個過程當中,instance 或者會不被計算)
直到 yield 語句全部被執行爲止。
因此,帶有 Block 的方法內部或者是這樣被執行的:
|def testblock(val){|instance| method }
| instance = val
| method
| instance = val
| method
|end
PS:以上不是可行方法,只是一個運行的示意圖
而 Block 跟迭代(Interation)根本沒有必然關係
PPS:以上全部是禾西在胡扯 |
|