2010-12-04 33 views
3

這是什麼問題?Ruby + =超載

class Vec2 
    attr_accessor :x, :y 
    # ... 
    def += (v) 
    @x += v.x 
    @y += v.y 
    return self 
    end 
    # ... 
end 

我一直沒能在網上找到太多。有人說這是因爲+ =在ruby中完成了調用+然後=,他在開玩笑吧?

在有趣的情況下,他是對的,有沒有一些解決方法(除了定義一個名爲「add」的方法)?

回答

6

有人說這是因爲在紅寶石+ =做致電+,然後=,他是在開玩笑吧?

不,他是對的(除了「calling =」有點不準確,因爲=不是一種方法)。

是否有一些解決方法(除了定義一個名爲「add」的方法)?

你的意思是除了定義+和生活+=會改變變量而不是對象?

您可以更改+來突出顯示對象,然後返回self,在這種情況下,v1 += v2將與v1 + v2相同,並會改變對象。不過,我強烈建議不要這樣做,因爲沒有人會預期+會發生變異(類似地,大多數有紅寶書意識的人會希望+=重新分配變量而不會變更對象,因此試圖改變這一點可能完全不可取)。

除此之外,不,沒有辦法解決這個問題。

4

他是對的。 +=是一種排序的語言結構,它將變量引用設置爲等於隱含的操作結果。 +=永遠實際上是一種方法和行爲符合預期:

a = [1, 2, 3] 
b = a 
b << 4 
b += [5, 6, 7] 
p a # => [1, 2, 3, 4] 
p b # => [1, 2, 3, 4, 5, 6, 7] 

ab這裏都包含相同的對象,這也就是爲什麼運行<<到一個元素添加到b也影響a引用。但是,我們可以看到,+=不應該修改對象本身;它應該改變存儲在該變量中的內容,這就是爲什麼a的值在這裏未被觸及的原因。

它確實與longhand完全等價。

b = a + [5, 6, 7] 

寫這樣一來,你期望能夠形成一個新的數組,併爲a保持不變。 +=就是這樣的簡寫,所以不會以任何方式變異a

你可以隨時定義你自己的+返回一個新的向量。

def +(v) 
    new_vector = self.class.new 
    new_vector.x = @x + v.x 
    new_vector.y = @y + v.y 
    new_vector 
end 
+0

實際上,我期望的確如此,即+ =修改變量引用的對象,而不是變量的內容,但我想這就是我。無論如何感謝您的答案:) – nespola 2010-12-04 14:29:38

+0

順便說一句,在代碼中它是@x + = v.x; @y + = v.y,因爲new_vector.x = @x + v,new_vector.y = @y + v沒有意義 – nespola 2010-12-04 14:34:41