我有以下代码:
use std::collections::HashSet;
fn translate() -> Option<String> {
None
}
fn main() {
let mut found = HashSet::new();
if let Some(tr) = translate() {
found.insert(tr);
}
}
它工作正常,但是当我在found.insert(tr)
之后删除分号时,出现编译错误:
error[E0308]: mismatched types
--> src/main.rs:11:9
|
7 | fn main() {
| - expected `()` because of default return type
...
11 | found.insert(tr)
| ^^^^^^^^^^^^^^^^- help: try adding a semicolon: `;`
| |
| expected (), found bool
|
= note: expected type `()`
found type `bool`
此代码的位置或函数的最后一个表达式无关紧要。
为什么编译器会假设花括号内的表达式应该是()
?
答案 0 :(得分:4)
根据Rust Book(强调我的):
表达式的值是选择的任何分支中最后一个表达式的值。没有
if
的else
始终会导致()
作为值。
这会对花括号内的表达式值进行约束。
这是正确的,因为表达式类型与()
匹配:
if let Some(_) = some() {
()
};
这是正确的,因为else
语句(以及分支之间的类型匹配):
if let Some(_) = some() {
true
} else {
false
};
但这是错误的:
if let Some(_) = some() {
true
};
这个答案的灵感来自this comment。
答案 1 :(得分:0)
当省略函数的返回类型时,该函数实际返回()
。也就是说,
fn foo() {}
相当于:
fn foo() -> () {}
如果我添加return();在函数结束时,我仍然得到相同的错误。所以我甚至不确定这是否与函数返回值有关。
用作语句的if let
表达式必须返回()
,除非它是函数体中的最后一个表达式,在这种情况下,其类型必须与函数&#39相匹配; s返回类型。由于您的if let
没有else
条款,因此其类型必须为()
。