为什么Rust不能推断出这种封闭性';什么是退货类型?
Rust编译器通常能够推断从闭包返回的表达式的类型:为什么Rust不能推断出这种封闭性';什么是退货类型?,rust,type-inference,Rust,Type Inference,Rust编译器通常能够推断从闭包返回的表达式的类型: fn main() { let a_closure = |num|{ num+1.0 }; println!("{}", a_closure(1.0)); } 但当我定义相同的闭包时,编译器无法推断类型: 我很惊讶Rust不能在这里推断出它的类型:在闭包中使用return语句而不阻止编译器推断它的返回类型吗?这是因为没有分号。如果没有分号,则返回最后一个表达式,最后一个表达式是re
fn main() {
let a_closure = |num|{
num+1.0
};
println!("{}", a_closure(1.0));
}
但当我定义相同的闭包时,编译器无法推断类型:
我很惊讶Rust不能在这里推断出它的类型:在闭包中使用
return
语句而不阻止编译器推断它的返回类型吗?这是因为没有分号。如果没有分号,则返回最后一个表达式,最后一个表达式是returnnum+1.0
。因为return语句使程序跳转到其他地方,所以它的值可以是任何值,例如:
fn main() {
let a: String = return;
}
但是,如果编译器没有看到分配给它的直接类型,它将选择类型()
作为返回语句的值
所以发生的事情是:
()
i32
因此,由于有两次尝试从闭包返回,并且它们各自返回不同的类型,这是一种类型不匹配。有趣的是,添加类型注释
num:f64
修复了使用return
时的编译。缺少推理可能会作为编译器的bug或功能请求提交。然而,令人困惑的错误消息可能被认为是一个bug。消息“expected()
,foundf64
”似乎不适用于此示例,注释num:f64
看起来也不应该影响它。消息适用于此错误,它说rustc将返回类型推断为()
,但我们返回的是f64
。请注意fn foo(){1.0f64}
如何触发完全相同的错误消息(除了建议添加返回类型)。调用a_闭包(1.0f64)
也可以解决此问题。向闭包添加显式返回类型也可以修复错误:num |->f64{return num+1.0}
@masklin如果编译器的推理由要求返回类型为()
的约束支持,则错误消息是合适的,但这里的情况并非如此。这就是为什么我认为这个消息令人困惑,或者至少误导人:它似乎暗示了这样一个约束,即它不存在。此外,foo
和返回foo之间的差异
(最后的分号没有区别)看起来像是一个直接的错误。这也是我的第一个猜测,但它是错误的:添加缺少的分号并不能修复错误。这无法解释为什么在代码中注释任何数字,return num+1.0f64
或a_closure(1.0f64)
或num:f64{…}
将导致错误消失,以及为什么此错误似乎只在数字类型推断中出现(尝试使用特定于字符串的方法;不会出错)
fn main() {
let a: String = return;
}