Types 为什么这个闭包参数需要显式类型?
考虑以下工作:Types 为什么这个闭包参数需要显式类型?,types,rust,Types,Rust,考虑以下工作: fn f(){ 设xs=vec![(0,0)]; 设f=| j | xs[j]; 设y=f(0usize); } 以下内容未编译: fn f(){ 设xs=vec![(0,0)]; 设f=| j | xs[j].0; 设y=f(0usize); } 它失败的原因如下: 错误[E0282]:需要类型注释 -->src/lib.rs:3:17 | 3 |设f=|j | xs[j].0; |^^^^无法推断类型 | =注意:此时必须知道类型 要修复它,必须注释j: fn f(){
fn f(){
设xs=vec![(0,0)];
设f=| j | xs[j];
设y=f(0usize);
}
以下内容未编译:
fn f(){
设xs=vec![(0,0)];
设f=| j | xs[j].0;
设y=f(0usize);
}
它失败的原因如下:
错误[E0282]:需要类型注释
-->src/lib.rs:3:17
|
3 |设f=|j | xs[j].0;
|^^^^无法推断类型
|
=注意:此时必须知道类型
要修复它,必须注释j
:
fn f(){
设xs=vec![(0,0)];
设f=|j:usize | xs[j].0;
设y=f(0usize);
}
报告说:
闭包不需要您注释参数或参数的类型
返回值与fn函数类似
为什么必须显式键入j
?正如@Stargateur建议的那样,Rust需要知道索引的类型,以便确定结果的类型。在第一个示例中,这不是一个问题,因为您既不使用xs[j]
也不使用闭包的结果,因此编译器可以随意将它们保留为“一些尚未定义的类型”,并在不需要知道类型的情况下对其进行优化
但是,在第二个示例中,您尝试访问
xs[j].0
,编译器需要知道xs[j]
的类型,以便知道如何处理。0
编译器需要知道xs[j]的类型,以便知道如何处理.0-那么也不应该编译吗?ÖmerErden在您的示例中,编译器发现从来没有使用过y
,因此我假设它没有尝试对rhs表达式进行完全的类型检查。在OP的情况下,xs[j].0
用作闭包的返回值。我假设编译器不能很容易地跨函数(或闭包)边界进行优化,这就是为什么它看不到所说的返回值从未被使用过并且可以忽略的原因。在我看来,编译器无法从索引(
的输出类型中找到索引(
的输入类型。这是正常的,因为根据输入的SliceIndex
的实现,输出可以是任何内容,但它看起来并不是从这一行推断输入类型f(0usize)
,也许问题应该是为什么它不是从f(0usize)
?如果是关于行顺序,它解释了为什么f(0usize).0
之所以有效,是因为输入类型已知。但我不知道类型检查器算法是如何工作的。很好的一点。我也不知道它是如何工作的,但这不是我第一次看到它在类型信息向前流动而不是向后流动时工作得更好。