2013-09-01 44 views
1

要填充一個數組,我可以寫[*2..10],它給出[2, 3, 4, 5, 6, 7, 8, 9, 10][* 2..10]如何工作?

這是如何工作的?

+1

它在Ruby語法中定義。它的工作原理是因爲他們將其定義爲可行 – lurker

+0

請查看http://stackoverflow.com/questions/918449/what-does-the-unary-operator-do-in-this-ruby-code,以及問題右側的鏈接答案。 –

+1

此外,「splat」測試是查看它應該做什麼的好方法:https://github.com/rubyspec/rubyspec/blob/master/language/splat_spec.rb –

回答

9

表達式2..10使用..運算符創建一個Range對象。

一般而言,*可以將數組展平,以便將單個對象轉換爲方法的單個參數列表。當應用於非數組對象時,它將嘗試首先通過調用to_a將對象轉換爲Array。因此,將*應用到Range上首先調用to_a,它返回位於該範圍內的值的數組。該陣列然後被平鋪爲*的值列表。

最後,將該值列表放在方括號內[ ... ]會生成新的Array。這與Rangeto_a的調用結果相同,但它沿途經過了一些額外的步驟(平坦化爲*,並且解除了[])。

注意,在賦值的右邊,你可以不用方括號,文字(x=1,2,3得到相同的結果x=[1,2,3])或splatted是否(x=*2..10產生相同的結果x=[*2..10])。

+0

'[]'是一個數組字面值,對任何事物來說,它都不是語法糖。 –

+0

謝謝,Jörg。固定。 –

0

(1..5).to_a

還銘記記住這x..y包括在範圍y,但x...y包括直到y,即:

(1...5).to_a 

產生[1,2,3,4]

+1

使用'...'運算符不是一個好主意。太多人不知道三點意味着什麼,這可能導致在調試和維護過程中出現錯誤。而不是說「包括'y'」可能更好地說它「排除'y'」。 –

+1

如果你只是創建一個範圍,那麼是的,'..'是最好的。但是你可能有一個更復雜的構造,你可以計算一些變量,但不包括某些變量。那麼使用'1 ... x'而不是'1 ..(x-1)'可能會更好。我假設這就是他們爲什麼要在語言中加入......的原因。 – Beartech

+0

這不提供問題的答案。要批評或要求作者澄清,請在其帖子下方留言。 – sawa

2

如果接收器是一個陣列,則splat運算符*解包接收器的元素。如果接收方不是數組,則使用方法to_a預先嚐試隱式類轉換。

在你的情況,範圍2..10不是數組,所以to_a嘗試,其成功,因爲Range#to_a被定義,並給出了[2, 3, 4, 5, 6, 7, 8, 9, 10]。 splat操作符在外部[]內解開該數組的元素,導致[2, 3, 4, 5, 6, 7, 8, 9, 10]