2010-05-24 82 views
18

我正在經歷的例子在書中的Ruby編程:並行賦值運算符在Ruby中

def fib_up_to(max) 
    i1, i2 = 1, 1 # parallel assignment (i1 = 1 and i2 = 1) 
    while i1 <= max 
    yield i1 
    i1, i2 = i2, i1+i2 
    end 
end 
fib_up_to(100) {|f| print f, " " } 

這只是打印Fibonacci數高達100這很好。當我用以下代替平行分配時:

i1 = i2 
i2 = i1+i2 

我沒有得到所需的輸出。

建議使用平行分配嗎?我來自Java背景,看到這種類型的賦值感覺真的很奇怪。

還有一個問題是:並行賦值操作符?

回答

30

在兩個單獨的語句中執行賦值的問題是i2 = i1 + i2將使用新值i1而不是正確生成斐波那契數列所需的先前值。

當您使用並行賦值時,首先評估右側的所有表達式,然後將其分配給左側的接收變量。

並行分配不是一個特殊的操作符。本質上,右側是數組,如果我們在左側列出多個變量,那麼數組將被解包並分配到相應的變量中。

下面是一些例子:

irb(main):020:0> a = 1, 2 # assign to a single variable 
=> [1, 2] 
irb(main):021:0> a 
=> [1, 2] 
irb(main):022:0> a, b = 1, 2 # unpack into separate variables 
=> [1, 2] 
irb(main):023:0> a 
=> 1 
irb(main):024:0> b 
=> 2 
irb(main):025:0> a, b = [1, 2, 3] # 3 is 'lost' as no receiving variable 
=> [1, 2, 3] 
irb(main):026:0> a 
=> 1 
irb(main):027:0> b 
=> 2 
irb(main):028:0> first, *rest = [1, 2, 3] # *rest consumes the remaining elements 
=> [1, 2, 3] 
irb(main):029:0> first 
=> 1 
irb(main):030:0> rest 
=> [2, 3] 

它是紅寶石的一個有用的特徵,例如,它有利於具有例如返回多個值的方法

def sum_and_difference(a, b) 
    a + b, a - b 
end 

sum, difference = sum_and_difference 5, 3 

在Java中最接近的事就是有一個返回int[]的方法,但是如果我們想返回一個字符串,以及一些我們需要創建一個小POJO作爲結構的返回值或返回Object[],並用代碼將代碼弄亂。請參閱我最近回答的this other question以獲得更實用的示例。

+0

謝謝你mikej !! – bragboy 2010-05-24 09:59:24

+2

您還可以: [1]'* from_first,last = 1,2,3,4' [2a]'* from_first => [1,2,3]' [2b]'last = 4' – funfuntime 2015-02-09 23:00:04

2

我在讀相同的東西,並有同樣的問題。這將是減少混亂,使更多的意義,如果它被寫成這樣:

def fib_up_to(max) 
    i1 = i2 = 1 
    while i1 <= max 
    yield i1 
    i1, i2 = i2, i1+i2 
    end 
end 

fib_up_to(100) {|f| print f, " " } 

使用i1, i2 = 1, 1沒有意義在我看來。但是這種類型的分配對於第5行是有意義的。

+0

對於'a = b = 1'類型的賦值,我一般會小心一點,因爲它與'a = 1不完全相同; b = 1「,但是」a =(b = 1)「,即」let'a「是」b = 1「的結果。 – Frost 2012-06-26 13:16:03

+3

@Frost爲什麼這不是一個好主意或者會出現什麼問題? – 2012-06-26 18:03:35