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

ide*_*n42 2 rust borrow-checker

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

虽然在函数外部分配变量始终是一个选项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);
    }
*/
}
Run Code Online (Sandbox Code Playgroud)

给出这个错误:

#[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);
    }
*/
}
Run Code Online (Sandbox Code Playgroud)

请参阅:婴儿围栏


[1]:尽管一次性赋值有时确实会提高可读性,但被迫将它们用作参数会鼓励使用作用域,以避免单次使用变量污染名称空间,导致函数调用原本会是一行 - 被包含在大括号和定义变量...如果可能的话,我想避免这种情况,特别是当借用检查器可以支持该要求时。

She*_*ter 5

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

这是否按预期工作

是的。

应该解决什么问题?

是的。

神奇的关键字是“非词汇生命周期”。现在,生命周期是词汇的——它们对应于我们输入的源代码块。理想情况下,foo.method(foo.mutable_method())会看到借用在“括号内”结束,但由于多种原因,它与整个语句相关联。

有关大量详细信息,请参阅RFC 问题 811以及从那里链接的所有内容。