不可变的字段和终身不匹配

时间:2013-08-03 01:51:02

标签: rust

鉴于此代码(也是here):

struct Vector2 {
    x: int,
    y: int
}

impl Vector2 {
    pub fn new(xs: int, ys: int) -> Vector2 {
        Vector2 { 
            x: xs,
            y: ys
        }
    }

    fn add(&self, otr: Vector2) -> &Vector2 { 
        self.x += otr.x; // cannot assign to immutable field (line 15)
        self.y += otr.y; // cannot assign to immutable field (line 16)
        return self; // lifetime mismatch                    (line 17)
    }
}

fn main() {
    let mut vec1 = Vector2::new(42, 12);
    println(fmt!("vec1 = [x: %?, y: %?]", vec1.x, vec1.y));

    let vec2 = Vector2::new(13, 34);
    println(fmt!("vec2 = [x: %?, y: %?]", vec2.x, vec2.y));

    let vec3 = vec1.add(vec2);
    println(fmt!("vec1 + vec2 = [x: %?, y: %?]", vec3.x, vec3.y))
}

我遇到第15-17行的问题。

对于第15和第16行,有人可以解释改变这两个变量的最佳方法是什么?我似乎没有正确使用self或者我在某个地方错过了mut

对于第17行,它给了我一个lifetime mismatch,也说:

  

不匹配类型:预期'& Vector2'但找到'& Vector2'...在14:41块上定义的匿名生命#1不一定比在14块上定义的匿名生命#2更长:41

有谁知道解决这两个问题的方法?

1 个答案:

答案 0 :(得分:3)

如果您希望add成为变异操作,则应该&mut self而不是&self

如果您希望add创建新的Vector2,请不要尝试改变self - 克隆它(假设0.8-pre;在0.7上,您将复制它而是使用copy self)并修改克隆,或创建具有相同类型的新实例。 (在add的情况下,这会更快。

当你在这里时,不要只有一个名为add的方法:实施std::ops::Add+将起作用! (目前还没有+=看到https://github.com/mozilla/rust/issues/5992。)

最终代码:

struct Vector2 {
    x: int,
    y: int,
}

impl Vector2 {
    pub fn new(x: int, y: int) -> Vector2 {
        Vector2 { 
            x: x,
            y: y,
        }
    }
}

impl Add<Vector2, Vector2> for Vector2 {
    fn add(&self, rhs: &Vector2) -> Vector2 {
        Vector2 {
            x: self.x + rhs.x,
            y: self.y + rhs.y,
        }
    }
}

fn main() {
    let vec1 = Vector2::new(42, 12);
    println(fmt!("vec1 = %?", vec1));
    // 0.8-pre hint: use printfln!(...) instead of println(fmt!(...))

    let vec2 = Vector2::new(13, 34);
    println(fmt!("vec2 = %?", vec2));

    let vec3 = vec1 + vec2;
    println(fmt!("vec1 + vec2 = %?", vec3));
}

及其输出:

vec1 = {x: 42, y: 12}
vec2 = {x: 13, y: 34}
vec1 + vec2 = {x: 55, y: 46}