我试图创建闭包矢量:
fn main() {
let mut vec = Vec::new();
vec.push(Box::new(|| 10));
vec.push(Box::new(|| 20));
println!("{}", vec[0]());
println!("{}", vec[1]());
}
Run Code Online (Sandbox Code Playgroud)
这产生了以下错误报告:
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
Run Code Online (Sandbox Code Playgroud)
我通过明确指定类型来修复它:
let mut vec: Vec<Box<Fn() -> i32>> = Vec::new();
Run Code Online (Sandbox Code Playgroud)
什么是推断类型,vec为什么会这样?
每个闭包都有一个自动生成的唯一匿名类型。将第一个闭包添加到向量后,即向量中所有项目的类型。但是,当您尝试添加第二个闭包时,它具有不同的自动生成的,唯一的匿名类型,因此您将列出错误。
闭包本质struct上是由实现特征之一的编译器创建的Fn*。struct闭包捕获的所有变量的contains字段,因此根据定义,它必须是唯一的,因为每个闭包将捕获不同数量和类型的变量。
为什么不能只是推断
Box<Fn() -> i32>呢?
“不能”是一个很难回答的问题。这是可能的,编译器可以通过使用的每一种,看一些路口导致代码编译类型的所有特征重复,但感觉有点不可思议给我。您可以尝试打开功能请求或在一个论坛上进行讨论,以查看是否普遍接受这种想法。
但是,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);
}
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1626 次 |
| 最近记录: |