【问题标题】:Why can a non-capturing closure be used after transferring ownership?为什么转移所有权后可以使用非捕获闭包?
【发布时间】:2020-11-17 01:39:58
【问题描述】:

我试图了解 Rust 中的所有权,但遇到了与所有权转让相关的误解。考虑以下代码:

fn main() {
    let closure = || 32;
    foo(closure);
    foo(closure); //perfectly fine
}

fn foo<F>(f: F) -> u32
where
    F: Fn() -> u32,
{
    f()
}

playground

我认为应该转让所有权,不应允许第二次调用foo(closure)

为什么会起作用?

【问题讨论】:

    标签: rust closures borrow-checker ownership


    【解决方案1】:

    你的闭包实现了Copy,所以当你第二次使用它时,会自动生成一个副本。您的代码的工作原理与此相同:

    fn main() {
        let v = 32;
        foo(v);
        foo(v);
    }
    
    fn foo(a: u32) -> u32 {
        a
    }
    

    另见:

    【讨论】:

    • 感谢您的意见。实际上,该行为在 reference 中得到了很好的说明: 如果闭包没有通过唯一的不可变或可变引用捕获任何值,并且如果它通过复制或移动捕获所有值,则闭包是 CloneCopy分别是CloneCopy
    • 对于那个特定的问题,这有点离题,但我想澄清一点关于捕获的闭包。假设闭包捕获了一些变量并在参数列表之前指定move 来获取它的所有权。如果在闭包的主体中使用对变量的引用,则捕获变量的生命周期将与闭包的生命周期相同,并且闭包将是Fn,而不是FnOnce
    • @SomeName move 和实现的特征是两个独立的概念。见When does a closure implement Fn, FnMut and FnOnce?。关于生命周期的问题,请参阅Why can't I store a value and a reference to that value in the same struct?,特别是以“生命周期是一点元数据”开头的段落
    猜你喜欢
    • 2018-05-26
    • 1970-01-01
    • 2019-06-16
    • 2019-07-26
    • 1970-01-01
    • 2019-10-13
    • 2013-01-25
    • 1970-01-01
    • 2020-05-04
    相关资源
    最近更新 更多