提问人:Preston 提问时间:7/31/2023 最后编辑:mkrieger1Preston 更新时间:7/31/2023 访问量:121
Rust 没有两个闭包,即使相同,也具有相同的类型 [duplicate]
Rust no two closures, even if identical, have the same type [duplicate]
问:
如何将两个具有相同定义的闭包放入一个?Vec
下面是一个最小的可重现示例:
fn main() {
let mut vec = Vec::new();
vec.push(Box::new(|| println!("test")));
vec.push(Box::new(|| println!("test2")));
vec.iter().for_each(|f| (f)());
}
编译失败,出现以下错误:
error[E0308]: mismatched types
--> src/main.rs:4:23
|
3 | vec.push(Box::new(|| println!("test")));
| -- the expected closure
4 | vec.push(Box::new(|| println!("test2")));
| -------- ^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure
| |
| arguments to this function are incorrect
|
= note: expected closure `[closure@src/main.rs:3:23: 3:25]`
found closure `[closure@src/main.rs:4:23: 4:25]`
= note: no two closures, even if identical, have the same type
= help: consider boxing your closure and/or using it as a trait object
答:
1赞
Aleksander Krauze
7/31/2023
#1
您必须明确告知 holds boxed trait 对象:vec
fn main() {
let mut vec: Vec<Box<dyn Fn()>> = Vec::new();
vec.push(Box::new(|| println!("test")));
vec.push(Box::new(|| println!("test2")));
vec.iter().for_each(|f| (f)());
}
另一方面,您可以保持原样并使用关键字“投射”盒装对象:as
fn main() {
let mut vec = Vec::new();
vec.push(Box::new(|| println!("test")) as Box<dyn Fn()>);
vec.push(Box::new(|| println!("test2")));
vec.iter().for_each(|f| (f)());
}
请注意,您只需要执行一次,因为现在 Rust 会推断出该类型的 is 确实,并且进一步推动将知道自动执行此转换。vec
Vec<Box<dyn Fn()>>
评论
0赞
PatientPenguin
7/31/2023
我相当确定,您可以向编译器暗示它需要强制,并让它找到正确的类型,而不是给出完整的类型。对于那些所有重要的击键节省as _
0赞
Aleksander Krauze
7/31/2023
@PatientPenguin不幸的是,这不起作用,并会导致以下错误。这是有道理的,因为 rust 无法知道要存储哪些特征对象(、、、或其他完全不同的东西)。an "as" expression can only be used to convert between primitive types or to coerce to a specific trait object
dyn Fn()
dyn FnOnce()
dyn FnMut()
1赞
PatientPenguin
7/31/2023
哦,你说得完全正确,我的错!
1赞
Masklinn
7/31/2023
@AleksanderKrauze对于这种特殊情况,由于闭包不会关闭任何内容,因此您不必将它们装箱,您可以将它们强制到静态函数指针 ()。fn()
评论
let mut vec: Vec<Box<dyn Fn()>> = Vec::new();
Vec<Box<SomeAnonymousConcreteType>>