0

我现在在 Rust 中面临一个借用问题,我有一个解决它的想法。但我认为我找到的方式不是一个好的答案。所以我想知道是否有另一种方法来解决它。

我使用以下示例代码来描述我的情况:

struct S {
    val: u8
}

impl S {
    pub fn f1(&mut self) {
        println!("F1");
        self.f2(self.val);
    }

    pub fn f2(&mut self, input: u8) {
        println!("F2");

        // Do something with input
    }
}

fn main() {
    let mut s = S {
        val: 0
    };

    s.f1();
}

StructureS有一个方法 ,f2它需要一个额外的参数input来做某事。还有另一种方法 ,它使用of 结构f1调用。局外人可能会调用其中一个或用于不同的用例。f2valSf1f2

当我编译上面的代码时,我收到以下错误消息:

src\main.rs:9:17: 9:25 error: cannot use `self.val` because it was mutably borrowed [E0503]
src\main.rs:9         self.f2(self.val);
                              ^~~~~~~~
src\main.rs:9:9: 9:13 note: borrow of `*self` occurs here
src\main.rs:9         self.f2(self.val);
                      ^~~~

我大致了解 Rust 中的借用是如何工作的。所以我知道我可以通过将实现更改f1为:

pub fn f1(&mut self) {
    let v = self.val;
    println!("F1");
    self.f2(v);
}

但是,我觉得这个解决方案有点多余。我想知道是否有办法在不使用额外变量绑定的情况下解决这个问题。

4

2 回答 2

3

您的解决方案之所以有效,不是因为额外的变量绑定,而是因为额外的copy。整数类型可以隐式复制,因此let v = self.val会创建值的副本。该副本不是借来的,self而是拥有的。所以编译器允许你f2用这个副本调用。

如果你写self.f2(self.val)了,编译器也会尝试复制self.val. 但是,在此位置无法进行复制,因为self它是为函数调用而借用的。因此,除非您复制之前的值,否则无法进行此类调用。这不是语法限制,而是借用检查器的强制执行。无论如何,最好按照实际发生的顺序编写复制和调用。

如果您尝试用作参数的类型不是Copy(例如 a String),则您需要编写let v = self.val.clone(); self.f2(v);以明确要求编译器进行复制。不允许在不复制的情况下拨打此类电话。您可能需要使方法不可变或以某种方式消除参数。

于 2016-08-25T17:26:08.057 回答
1

您可以将此技巧用于可复制值:

pub fn f1(&mut self) {
    println!("F1");
    match self.val {x => self.f2(x)};
}

但是,使用显式临时变量更加清晰和惯用。

于 2016-08-25T19:00:58.587 回答