我试图创建闭包矢量:
fn main() {
let mut vec = Vec::new();
vec.push(Box::new(|| 10));
vec.push(Box::new(|| 20));
println!("{}", vec[0]());
println!("{}", vec[1]());
}
产生了以下错误报告:
error[E0308]: mismatched types
--> src/main.rs:5:23
|
5 | vec.push(Box::new(|| 20));
| ^^^^^ expected closure, found a different closure
|
= note: expected type `[closure@src/main.rs:4:23: 4:28]`
found type `[closure@src/main.rs:5:23: 5:28]`
= note: no two closures, even if identical, have the same type
= help: consider boxing your closure and/or using it as a trait object
我通过明确指定类型来修复它:
let mut vec: Vec<Box<Fn() -> i32>> = Vec::new();
vec
的推断类型是什么?为什么会这样?
答案 0 :(得分:5)
每个闭包都有一个自动生成的,唯一的匿名类型。只要将第一个闭包添加到向量,就是向量中所有项的类型。但是,当您尝试添加第二个闭包时,它具有不同的自动生成,唯一,匿名类型,因此您会收到列出的错误。
闭包基本上是struct
s,由编译器创建,实现Fn*
个特征之一。 struct
包含闭包捕获的所有变量的字段,因此根据定义它需要是唯一的,因为每个闭包将捕获不同数量和类型的变量。
为什么它只能推断
Box<Fn() -> i32>
?
&#34;可以&#39; T&#34;这是一个难以回答的问题。它可能编译器可以遍历每个类型的所有特征,用于查看某个交集是否导致代码编译,但这对我来说有点神奇。您可以尝试打开功能请求或在其中一个论坛上讨论它,看看是否普遍接受这样的想法。
然而,Rust确实试图使事情明确,特别是可能涉及性能的事情。当你从一个具体的结构转移到一个特征对象时,你会引入间接性,它可能会变慢。
现在,Fn*
特征的作用与用户构造的特征相同:
trait MyTrait {
fn hello(&self) {}
}
struct MyStruct1;
impl MyTrait for MyStruct1 {}
struct MyStruct2;
impl MyTrait for MyStruct2 {}
fn main() {
let mut things = vec![];
things.push(MyStruct1);
things.push(MyStruct2);
}
error[E0308]: mismatched types
--> src/main.rs:14:17
|
14 | things.push(MyStruct2);
| ^^^^^^^^^ expected struct `MyStruct1`, found struct `MyStruct2`
|
= note: expected type `MyStruct1`
found type `MyStruct2`