2010-12-04 34 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