rust - 在我克隆它之前,Vector 的生命周期不够长

标签 rust borrow-checker

我不明白为什么 v 在片段 (2) 中的生命周期不够长,但它在其他情况下有效。如果我不需要克隆 (1) 中的变量,为什么我需要克隆它才能使第二种情况起作用?

fn main() {
    // (1)
    let v = make_vec().unwrap();
    let m = v.last();

    // (2) v doesn't live long enough!
    let m = make_vec()
        .and_then(|v| v.last());

    // (3) Fixed!
    let m = make_vec()
        .and_then(|v| v.last().cloned());
}

fn make_vec() -> Option<Vec<u32>> {
    Some(vec![1, 2, 3])
}

最佳答案

在第一种情况下,Option 的所有权从 make_vec 传递到 unwrap称呼。 unwrap 消费 Option 并返回 Vec ,其所有权传递给变量 v .调用last返回对 v 的引用.

在第二种情况下,Option 的所有权从 make_vec 传递调用and_then . and_then 消耗 Option , 并传递 Vec 的所有权到关闭。调用last在闭包中返回对 Vec 的引用.由于闭包拥有向量但现在已完成运行,Vec将被丢弃。引用到Vec将指向不再有效的内存,因此会出现编译错误。

在第三种情况下,Option 的所有权从 make_vec 传递调用and_then . and_then 消耗 Option , 并传递 Vec 的所有权到关闭。调用last在闭包中返回对 Vec 的引用.引用的项目被克隆,这将创建一个不同于 Vec 的新项目.当 Vec在关闭后被丢弃,没有可能导致问题的引用。

m 的类型你的情况不同。第一种和第二种情况将返回 Option<&u32>。如果他们都工作。第三种情况返回 Option<u32> .

还有第四种选择:

let r = make_vec();
let m = r.as_ref().and_then(|v| v.last());

这会转换 Option<T>进入 Option<&T> .这个新Option引用 original 选项,可以通过调用 and_then 使用.

还有第五种选择! ^_^ 如果你只是打算扔掉向量,你可以更明确地说明你无论如何都想接受它:

let m = make_vec().and_then(|v| v.pop());

Does clone here actually copy things in memory or will the compiler optimise it to effectively pass the ownership of the vector element back? Since this was u32s throughout, I was expecting that they would generally be copied instead of referenced.

优化是一件棘手的事情,唯一真正的答案是查看优化后的输出。 会假设任何Copy并且“足够小”不会真正造成问题。但是,我可能会考虑让我的代码尽可能语义化,以帮助优化器。我可能会尝试使用 pop变体,如果该代码是你的意思。

关于rust - 在我克隆它之前,Vector 的生命周期不够长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34535936/

相关文章:

rust - 借用检查器检查可变引用的最佳实践是什么?

rust - 移动关闭的特征?

rust - 为什么在使用 and_then 组合器时我的错误类型没有自动更改?

rust - 关于可变内部引用的 Rust 借用规则是什么?

rust - 无法移动 dyn 类型的值 <'r> FnOnce(&' r mut [u8]) : the size of dyn for <'r> FnOnce(&' r mut [u8]) cannot be statically determined

rust - 如何解决 "indicate anonymous lifetime <' _>”错误?

rust - 如何在编译时创建静态字符串

rust - 如何将路径转换为 ​​FFI 的 const char*?

rust - 为什么转移所有权后可以使用非捕获闭包?

rust - Const 闭包数组采用对 Rust 中具有生命周期参数的结构的可变引用