Rust 为什么编译器假定if let的值应该是“()”?

Rust 为什么编译器假定if let的值应该是“()”?,rust,Rust,我有以下代码: use std::collections::HashSet; fn translate() -> Option<String> { None } fn main() { let mut found = HashSet::new(); if let Some(tr) = translate() { found.insert(tr); } } 不管此代码位于何处,也不管它是否是函数的最后一个表达式 为什么编译器

我有以下代码:

use std::collections::HashSet;

fn translate() -> Option<String> {
    None
}

fn main() {
    let mut found = HashSet::new();

    if let Some(tr) = translate() {
        found.insert(tr);
    }
}
不管此代码位于何处,也不管它是否是函数的最后一个表达式


为什么编译器假定大括号内的表达式应该是
()

当您省略函数的返回类型时,函数实际上返回
()
。就是

fn foo() {}
相当于:

fn foo() -> () {}

如果我添加return();在函数结束时,我仍然得到相同的错误。所以我甚至不确定这是否与函数返回值有关

用作语句的
if let
表达式必须返回
()
,除非它是函数体中的最后一个表达式,在这种情况下,其类型必须与函数的返回类型匹配。由于您的
if let
没有
else
子句,因此其类型必须是
()

(我的重点):

表达式的值是所选分支中最后一个表达式的值。如果
if
没有
else
则总是将
()
作为值

这将对花括号内的表达式值进行约束

这是正确的,因为表达式类型匹配
()

这是正确的,因为有一个
else
语句(分支之间的类型匹配):

但这是错误的:

if let Some(_) = some() {
    true
};

这个答案是受到了他的启发

如果我添加return();在函数结束时,我仍然得到相同的错误。因此,我甚至不确定这是否与函数返回值有关。我想象
if
表达式没有和
else
必须具有类型
()
,因为缺少的
else
表达式隐式具有类型
()
insert
返回
bool
,因此这两个分支具有不同的类型。添加分号会导致
if
块的类型为
()
。我认为您是对的(而且不是很明显)。添加else{false}也可以解决这个问题。您认为编译器在这里应该更灵活,还是按预期工作?谢谢
if let Some(_) = some() {
    true
} else {
    false
};
if let Some(_) = some() {
    true
};