首页 > 解决方案 > 为什么这个闭包参数需要一个显式类型?

问题描述

考虑以下工作代码

fn f() {
    let xs = vec![(0, 0)];
    let f = |j| xs[j];
    let y = f(0usize);
}

以下变体无法编译:

fn f() {
    let xs = vec![(0, 0)];
    let f = |j| xs[j].0;
    let y = f(0usize);
}

它失败如下:

error[E0282]: type annotations needed
 --> src/lib.rs:3:17
  |
3 |     let f = |j| xs[j].0;
  |                 ^^^^^ cannot infer type
  |
  = note: type must be known at this point

要修复它,必须注释j

fn f() {
    let xs = vec![(0, 0)];
    let f = |j: usize| xs[j].0;
    let y = f(0usize);
}

锈书说:

闭包不需要您像 fn 函数那样注释参数的类型或返回值。

为什么必须j显式键入?

标签: typesrust

解决方案


正如@Stargateur 建议的副本中所解释的,Rust 需要知道索引的类型,以便它可以确定结果的类型。在您的第一个示例中,这不是问题,因为您既不使用xs[j]也不使用闭包的结果,因此编译器可以随意将它们保留为“一些尚未定义的类型”并优化它们而无需知道类型.

但是,在您的第二个示例中,您尝试访问xs[j].0,编译器需要知道其类型xs[j]才能知道如何处理.0.


推荐阅读