使用'as'的第一次转换会编译,但是使用'From'特性的第二次转换不会编译:

fn main() {
    let a: u64 = 5;
    let b = a as usize;
    let b = usize::from(a);
}

使用Rust 1.34.0,我得到以下错误:

error[E0277]: the trait bound `usize: std::convert::From<u64>` is not satisfied
 --> src/main.rs:4:13
  |
4 |     let b = usize::from(a);
  |             ^^^^^^^^^^^ the trait `std::convert::From<u64>` is not implemented for `usize`
  |
  = help: the following implementations were found:
            <usize as std::convert::From<bool>>
            <usize as std::convert::From<std::num::NonZeroUsize>>
            <usize as std::convert::From<u16>>
            <usize as std::convert::From<u8>>
  = note: required by `std::convert::From::from`

当我用u64替换u8时,没有更多错误了。从错误消息中,我了解到From特性仅适用于u8,而不适用于其他整数类型。

如果有充分的理由,那么为什么使用'as'进行的转换也不应编译失败呢?

最佳答案

as强制转换与From转换从根本上不同。 From转换是“简单和安全”,而as强制转换纯粹是“安全”。在考虑数字类型时,仅在保证输出相同的情况下才存在From转换,即,不会丢失任何信息(不会出现截断或下限或精度下降)。 as强制转换没有此限制。

引用文档,



由于大小取决于目标体系结构,并且无法在编译之前确定大小,因此不能保证在数字类型和From之间进行usize转换。但是,as强制转换将始终按照here列出的规则进行操作。

例如,在32位系统上,usize等效于u32。由于usize小于u64,因此在将u64转换为usize时可能会丢失信息(截断),因此From转换将不存在。但是,usize的大小始终保证为8位或更大,并且u8usizeFrom转换将始终存在。

10-02 03:13
查看更多