对于下面代码
#![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(());
}
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(());
}
他就会报 这样的错误
按照提示修改后,通过了编译。又为什么这样写呢?
1
共 6 条评论, 1 页
评论区
写评论the reference 这本书就大体翻了翻,看来还是要仔细看一下
--
👇
苦瓜小仔: 对了,闭包的 trait 实现规则是明确被官方记录的,如果你想描述闭包的脱糖形式,别忘了考虑它们:)
https://doc.rust-lang.org/reference/types/closure.html#other-traits
对了,闭包的 trait 实现规则是明确被官方记录的,如果你想描述闭包的脱糖形式,别忘了考虑它们:)
https://doc.rust-lang.org/reference/types/closure.html#other-traits
明白了,感谢两位大佬
闭包适时自动实现 Copy,这会让你编写愉悦的代码;即便是没有实现 Copy 的闭包, call_once 也不意味着你只能调用一次。
如果对这个细节感到奇怪,考虑以下情况:
有什么理由让 f 只用一次呢?
闭包会根据捕获的变量类型,自动实现某些
trait
, 比如Copy
.第一个闭包捕获的是不可变引用,
&T: Copy
, 因此也是Copy
.第二个闭包捕获的是可变引用, 可变引用没有实现
Copy
, 因此闭包也没有实现Copy
.在某些情况,闭包结构体会实现 Copy,正如你看到的通过的例子。
注意 Rust 的闭包脱糖方式没有官方说明,所以
.call_once
是不是多次真的调用一次并不重要(因为 Copy 只会在适时的情况下被实现)。这种细节最好参考编译器人员的博客(或者阅读源码),rustyyato 的闭包脱糖文章已经很经典了 https://rustyyato.github.io/rust/syntactic/sugar/2019/01/17/Closures-Magic-Functions.html