使用'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位或更大,并且u8
到usize
的From
转换将始终存在。