闭包向量的推断类型是什么? [英] What is the inferred type of a vector of closures?

查看:47
本文介绍了闭包向量的推断类型是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试创建闭包向量:

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

我通过明确指定类型来修复它:

I fixed it by specifying the type explicitly:

let mut vec: Vec<Box<Fn() -> i32>> = Vec::new();

vec 的推断类型是什么,为什么会这样?

What is the inferred type of vec and why is it that way?

推荐答案

每个闭包都有一个自动生成的、唯一的、匿名的类型.一旦将第一个闭包添加到向量中,这就是向量中所有项目的类型.但是,当您尝试添加第二个闭包时,它具有不同的自动生成的、唯一的、匿名的类型,因此您会得到列出的错误.

Each closure has an auto-generated, unique, anonymous type. As soon as you add the first closure to the vector, that is the type of all items in the vector. However, when you try to add the second closure, it has a different auto-generated, unique, anonymous type, and so you get the error listed.

闭包本质上是由编译器创建的 struct 实现了 Fn* 特征之一.struct 包含闭包捕获的所有变量的字段,因此根据定义它必须是唯一的,因为每个闭包将捕获不同数量和类型的变量.

Closures are essentially structs that are created by the compiler that implement one of the Fn* traits. The struct contains fields for all the variables captured by the closure, so it by definition needs to be unique, as each closure will capture different numbers and types of variables.

为什么它不能只是推断 Box<Fn() ->i32>?

Why can't it just infer Box<Fn() -> i32>?

不能"是一个很难回答的问题.可能 编译器可以遍历每种类型的所有特征,以查看是否存在某种交集导致代码编译,但这对我来说有点神奇.您可以尝试提出功能请求或在其中一个论坛上进行讨论,看看是否有人普遍接受这样的想法.

"can't" is a tough question to answer. It's possible that the compiler could iterate through all the traits of every type that is used to see if some intersection caused the code to compile, but that feels a bit magical to me. You could try opening a feature request or discussing it on one of the forums to see if there is general acceptance of such an idea.

然而,Rust 确实试图使事情变得明确,尤其是可能涉及性能的事情.当你从一个具体的结构体到一个 trait 对象时,你就引入了间接性,这可能会变慢.

However, Rust does try to make things explicit, especially things that might involve performance. When you go from a concrete struct to a trait object, you are introducing indirection, which has the possibility of being slower.

现在,Fn* trait 的工作方式与用户构建的 trait 相同:

Right now, the Fn* traits work the same as a user-constructed trait:

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`

这篇关于闭包向量的推断类型是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆