我正在使用《理解 Rust 中的闭包》中的示例。。我定义了以下结构:
struct MyStruct {
text: &'static str,
number: u32,
}
impl MyStruct {
fn new(text: &'static str, number: u32) -> MyStruct {
MyStruct {
text: text,
number: number,
}
}
// We have to specify that 'self' is an argument.
fn get_number(&self) -> u32 {
self.number
}
// We can specify different kinds of ownership and mutability of self.
fn inc_number(&mut self) {
self.number += 1;
}
// There are three different types of 'self'
fn destructor(self) {
println!("Destructing {}", self.text);
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了这些“测试”函数来根据编译时错误对闭包进行分类:
fn is_fn<A, R>(_x: fn(A) -> R) {}
fn is_Fn<A, R, F: Fn(A) -> R>(_x: &F) {}
fn is_FnMut<A, R, F: FnMut(A) -> R>(_x: &F) {}
fn is_FnOnce<A, R, F: FnOnce(A) -> R>(_x: &F) {}
Run Code Online (Sandbox Code Playgroud)
本文演示了以下示例作为FnOnce闭包:
let obj1 = MyStruct::new("Hello", 15);
let obj2 = MyStruct::new("More Text", 10);
// obj1 is owned by the closure
let mut closure4 = move |x: &MyStruct| {
obj1.destructor();
x.get_number()
};
is_FnMut(&closure4);
Run Code Online (Sandbox Code Playgroud)
这有一个编译错误:
struct MyStruct {
text: &'static str,
number: u32,
}
impl MyStruct {
fn new(text: &'static str, number: u32) -> MyStruct {
MyStruct {
text: text,
number: number,
}
}
// We have to specify that 'self' is an argument.
fn get_number(&self) -> u32 {
self.number
}
// We can specify different kinds of ownership and mutability of self.
fn inc_number(&mut self) {
self.number += 1;
}
// There are three different types of 'self'
fn destructor(self) {
println!("Destructing {}", self.text);
}
}
Run Code Online (Sandbox Code Playgroud)
这就说得通了。根据我的理解,编译器推断该值已移至闭包中,因为调用了析构函数。
我试图看看还有什么原因导致关闭被推断为FnOnce。我将闭包声明为move闭包:
let obj1 = MyStruct::new("Hello", 15);
let obj2 = MyStruct::new("More Text", 10);
// obj1 is owned by the closure
let mut closure4 = move |x: &MyStruct| {
obj1.get_number();
x.get_number()
};
is_Fn(&closure4);
is_FnMut(&closure4);
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,这实际上已经过去了,所以这个闭包实际上被认为是也Fn,而不是完全FnOnce像我预期的那样。这是为什么?我认为如果一个值被移入闭包,它不会实现,Fn而只会实现FnOnce。
所以我想,“好吧,也许不知何故并obj1没有真正进入关闭状态,让我测试一下”。obj1所以我尝试在构造后以任何方式使用closure4,编译器表明obj1确实已移入闭包:
let obj1 = MyStruct::new("Hello", 15);
let obj2 = MyStruct::new("More Text", 10);
// obj1 is owned by the closure
let mut closure4 = move |x: &MyStruct| {
obj1.get_number();
x.get_number()
};
obj1.get_number();
Run Code Online (Sandbox Code Playgroud)
fn is_fn<A, R>(_x: fn(A) -> R) {}
fn is_Fn<A, R, F: Fn(A) -> R>(_x: &F) {}
fn is_FnMut<A, R, F: FnMut(A) -> R>(_x: &F) {}
fn is_FnOnce<A, R, F: FnOnce(A) -> R>(_x: &F) {}
Run Code Online (Sandbox Code Playgroud)
有人可以为我启发这种行为吗?对于不实现fn、、、而仅实现的闭包Fn,必须满足什么条件?FnMutFnOnce
| 归档时间: |
|
| 查看次数: |
1496 次 |
| 最近记录: |