借用 Rust 中的检查器和函数参数,正确还是过度热心?

Borrow checker and function arguments in Rust, correct or over zealous?

当可变参数作为函数参数传递时,借用检查器不允许将其用于构造其他参数,即使这些参数在没有引用的情况下克隆值也是如此。

虽然在函数外部分配变量始终是一个选项1,但从逻辑上讲,这似乎过于热心,借用检查器可能会考虑到这一点。

这是按预期工作还是应该解决的问题?

#[derive(Debug)]
struct SomeTest {
    pub some_value: f64,
    pub some_other: i64,
}

fn some_fn(var: &mut SomeTest, other: i64) {
    println!("{:?}, {}", var, other);
}

fn main() {
    let mut v = SomeTest { some_value: 1.0, some_other: 2 };
    some_fn(&mut v, v.some_other + 1);

    // However this works!
/*
    {
        let x = v.some_other + 1;
        some_fn(&mut v, x);
    }
*/
}

出现此错误:

  --> src/main.rs:14:21
   |
14 |     some_fn(&mut v, v.some_other + 1);
   |                  -  ^^^^^^^^^^^^ use of borrowed `v`
   |                  |
   |                  borrow of `v` occurs here

参见:playpen


[1]:尽管一次性赋值有时确实提高了可读性,但被迫将它们用于参数会鼓励使用作用域以避免一次性变量污染名称 -space,导致函数调用否则将是一行 - 被括在大括号中并定义变量......我想尽可能避免这种情况,特别是当需求看起来像是借用检查器可以支持的东西时。

这是借用检查器当前实现的产物。这是一个众所周知的限制,至少可以追溯到 2013 年,但没有人对此感到高兴。

Is this working as intended

是的。

something that should be resolved?

是的。

魔术关键字是"non-lexical lifetimes"。现在,生命周期是词法的——它们对应于我们输入的源代码块。理想情况下,foo.method(foo.mutable_method()) 会看到借位结束 "inside the parenthesis",但由于种种原因,它与整个语句相关联。

有关更多信息,请参阅 RFC issue 811 以及从那里链接的所有内容。