为什么这个闭包参数需要显式类型?

Lis*_*one 5 types rust

考虑以下工作代码

\n\n
fn f() {\n    let xs = vec![(0, 0)];\n    let f = |j| xs[j];\n    let y = f(0usize);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

以下变体无法编译:

\n\n
fn f() {\n    let xs = vec![(0, 0)];\n    let f = |j| xs[j].0;\n    let y = f(0usize);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

它失败如下:

\n\n
error[E0282]: type annotations needed\n --> src/lib.rs:3:17\n  |\n3 |     let f = |j| xs[j].0;\n  |                 ^^^^^ cannot infer type\n  |\n  = note: type must be known at this point\n
Run Code Online (Sandbox Code Playgroud)\n\n

要修复它,必须注释j

\n\n
fn f() {\n    let xs = vec![(0, 0)];\n    let f = |j: usize| xs[j].0;\n    let y = f(0usize);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

Rust书中说:

\n\n
\n

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

\n
\n\n

为什么必须j显式键入?

\n

Jmb*_*Jmb 0

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

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