我正在努力理解Rust的规则是什么,大约是!和类型判断.

此函数执行类型判断:

fn works<E>(r: Result<i32, E>) -> i32 {
    match r {
        Ok(v) => v,
        Err(_) => {
            panic!("bad");
        }
    }
}

而这一次则没有:

fn fails<E>(r: Result<i32, E>) -> i32 {
    match r {
        Ok(v) => v,
        Err(_) => {
            panic!("bad");
            ()
        }
    }
}

这似乎与我是否真的 Select 了不稳定的!功能无关.对于fails,我收到关于无法访问代码的警告,以及关于Err ARM返回()而不是i32的错误(E0308).

为什么会有这样的区别?我的印象是,{ E; }{ E; () }之间真的没有区别--前者没有最终操作数,隐式地()也是,而后者有最终操作数,也是……明确地说是().但在这种情况下,panic!的存在会导致;不起作用.

{ panic!("bad"); }真的有!类型吗?或者有没有其他方式编译器只是简单地 suppress 错误?

推荐答案

我不认为这是记录在案的,我不知道这是否是故意的--您可以try 报告一个错误.

这种差异源于这样一个事实:当块中有尾表达式时,编译器首先期望它与预期的返回类型匹配,如果不匹配,则发出错误.只有到那时,它才会判断块是否有分歧(有一个返回!的表达式),如果有,则允许任何类型,但错误已经发出.

Here the compiler checks the type of the tail expressionhere it allows any type if the block diverges.

This is somewhat documented in rustc's source code:

// Subtle: if there is no explicit tail expression,
// that is typically equivalent to a tail expression
// of `()` -- except if the block diverges. In that
// case, there is no value supplied from the tail
// expression (assuming there are no other breaks,
// this implies that the type of the block will be
// `!`).

Rust相关问答推荐

为什么拥有的trait对象的相等运算符移动了正确的操作数?

如何为utoipa中的可选查询参数生成OpenAPI模式?

为什么reqwest以文本形式下载二进制文件?

铁 rust 中的共享对象实现特征

不能在Rust中使用OpenGL绘制三角形

为相同特征的特征对象使用 move 方法实现特征

如何对一个特征的两个实现进行单元测试?

从管道读取后重置标准输入

提取指向特征函数的原始指针

为什么Rust编译器会忽略模板参数应具有静态生命周期?

如何在 Rust 中按 char 对字符串向量进行排序?

试图理解 Rust 中的可变闭包

如何在 Rust Polars 中可靠地连接 LazyFrames

无法把握借来的价值不够长寿,请解释

隐式类型闭包的错误生命周期推断

类型组的通用枚举

Rust:如果我知道只有一个实例,那么将可变borrow 转换为指针并返回(以安抚borrow 判断器)是否安全?

有没有办法在 Rust 中对 BigInt 进行正确的位移?

为什么这里需要类型注解?

守卫如何影响匹配语句?