2015-12-30 125 views
3

看來我們總是可以使用&:+。爲什麼inject需要:+map必須採取&:to_s?如果原因是map不能採取符號,但必須採取一個塊,那麼如果map也需要一個符號是否有意義?爲什麼我們可以說`arr.inject(:+)`,但不得不說`arr.map(&:to_s)`?

[1,3,5].inject(:+) # => 9 
[1,3,5].inject(&:+) # => 9 
[1,3,5].map(&:to_s) # => ["1", "3", "5"] 
[1,3,5].map(:to_s) # => ArgumentError: wrong number of arguments (1 for 0) 
+0

@ user2864740我在另一篇文章中看到,':to_s'返回塊 –

+0

考慮,你可以寫'arr.inject(:+)'或'arr.inject(:+)',考慮改變你的問題是爲什麼[Enumerable#map](http://ruby-doc.org/core-2.2.0/Enumerable.html#method-i-map)沒有允許參數爲符號的表單,作爲[Enumerable#inject](http://ruby-doc.org/core-2.2.0/Enumerable.html#method-i-inject)(又名'reduce')。這不是你的意思嗎? –

+0

是的,如果'inject'可以帶一個符號,那麼爲什麼它不是,至少在上面的例子中,'map'也是一個符號呢? –

回答

4

它是由設計。 inject允許替代語法採取符號,而map總是需要一個塊。

可能的原因符號參數是允許在inject但不是在map是因爲inject總是返回得到的迭代的對象,而map被設計爲當一個塊是不存在返回一個Enumerator實例。如果該塊不存在,如果必須查看是否提供符號參數以決定是返回Enumerator還是映射的Array實例,則會變得複雜。因此,Ruby設計人員對諸如map之類的方法做了一個簡單的規則,即塊的缺失意味着返回值將是Enumerator

具有諷刺意味的是,inject允許符號的缺點是符號不能作爲inject中的初始值傳遞。但是,Ruby的設計者可能會認爲這種情況很罕見。

+1

':to_s'也是一個符號。請提供適用的參考資料/實例來說明行爲。 – user2864740

+0

@sawa是否有缺點,如果'地圖'也可以採取一個符號? –

+1

認真思考。只有'inject'允許它是一個符號的參數纔有一個很好的理由。 (我不知道。) –

4

這是設計。具體來說,inject/reduce不需要完整的symbol-to-proc語法(&:+),但它們允許只傳遞一個符號(:+)(這是一種不同的行爲)。

請注意,在這種特定情況下,傳遞符號與傳遞從符號派生的proc不同。

From the Ruby documentation

通過施加二進制運算,通過符號名稱的方法或操作者指定的結合了枚舉的所有元素。

如果指定一個塊,那麼對於enum中的每個元素,該塊將傳遞一個累加器值(備註)和該元素。如果您改爲指定一個符號,則集合中的每個元素都將被傳遞給指定的備忘錄方法。無論哪種情況,結果都會成爲備忘錄的新值。在迭代結束時,備忘錄的最終值是該方法的返回值。

+0

我想OP想知道爲什麼'map'不允許它的參數是一個符號。 –

+2

@CarySwoveland如果是這樣的話,這是隱含在我的迴應。但爲了以防萬一,這是迴應。他的假設是':+'和'&:+'是相同的東西,而不是。前者是一個象徵,後者是一個符號的過程。 'map'不接受符號,因爲該方法被設計爲接受block/proc而不是符號。 –

+0

哦,我確實說過:「如果原因是地圖不能帶符號但必須擋住一塊,那麼如果地圖也需要一個符號,它會有意義嗎?」 –

相關問題