< 返回版块

abliger 发表于 2023-03-28 22:29

对于下面代码

#![feature(fn_traits)]
#[derive(Debug)]
struct Test {
    num: i32,
    b: bool,
}
fn main() {
    let test = Test { num: 33, b: true };
    let a = || {
        println!("{:?}", &test);
    };
    println!("{:?}", &test);
    a.call_once(());
    //a.call_mut(());
    a.call(());
}

code

FnOnce 的 call_once 参数是 self。 对于实现了 Fn trait 的闭包 a,我先调用 call_once ,a 的所有权不就被消耗掉了吗?为什么我还能继续使用 a.call?

但对与一个实现 FnMut 的闭包 a,代码如下

#![feature(fn_traits)]
#[derive(Debug)]
struct Test {
    num: i32,
    b: bool,
}
fn main() {
    let mut test = Test { num: 33, b: true };
    let mut a = || {
        println!("{:?}", &mut test);
    };
    //println!("{:?}", &test);
    a.call_once(());
    a.call_mut(());
    //a.call(());
}

他就会报 这样的错误

code

按照提示修改后,通过了编译。又为什么这样写呢?

评论区

写评论
作者 abliger 2023-03-29 13:30

the reference 这本书就大体翻了翻,看来还是要仔细看一下

--
👇
苦瓜小仔: 对了,闭包的 trait 实现规则是明确被官方记录的,如果你想描述闭包的脱糖形式,别忘了考虑它们:)

https://doc.rust-lang.org/reference/types/closure.html#other-traits

苦瓜小仔 2023-03-29 10:42

对了,闭包的 trait 实现规则是明确被官方记录的,如果你想描述闭包的脱糖形式,别忘了考虑它们:)

https://doc.rust-lang.org/reference/types/closure.html#other-traits

作者 abliger 2023-03-28 23:24

明白了,感谢两位大佬

苦瓜小仔 2023-03-28 23:11

闭包适时自动实现 Copy,这会让你编写愉悦的代码;即便是没有实现 Copy 的闭包, call_once 也不意味着你只能调用一次。

如果对这个细节感到奇怪,考虑以下情况

    {
        let f = || {
            println!("{:?}", &test);
        };

        None::<()>.unwrap_or_else(f);
        Some(()).unwrap_or_else(f);
    }

    {
        let mut f = || {
            println!("{:?}", &mut test);
        };

        None::<()>.unwrap_or_else(&mut f);
        Some(()).unwrap_or_else(&mut f);
    }

有什么理由让 f 只用一次呢?

Grobycn 2023-03-28 23:06

闭包会根据捕获的变量类型,自动实现某些 trait, 比如 Copy.

第一个闭包捕获的是不可变引用,&T: Copy, 因此也是 Copy.

第二个闭包捕获的是可变引用, 可变引用没有实现 Copy, 因此闭包也没有实现 Copy.

苦瓜小仔 2023-03-28 22:56

在某些情况,闭包结构体会实现 Copy,正如你看到的通过的例子。

注意 Rust 的闭包脱糖方式没有官方说明,所以 .call_once 是不是多次真的调用一次并不重要(因为 Copy 只会在适时的情况下被实现)。

这种细节最好参考编译器人员的博客(或者阅读源码),rustyyato 的闭包脱糖文章已经很经典了 https://rustyyato.github.io/rust/syntactic/sugar/2019/01/17/Closures-Magic-Functions.html

1 共 6 条评论, 1 页