使用'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
演员没有这个限制。
引用文档,
[
usize
]的大小是“引用内存中任何位置所需的字节数。例如,在32位目标上,这是4个字节,在64位目标上,这是8个字节。”
由于大小取决于目标体系结构,并且在编译之前无法确定,因此无法保证数字类型和From
之间的usize
转换是可能的。然而,as
演员将始终按照here列出的规则运作。
例如,在32位系统上,usize
相当于u32
。由于usize
小于u64
,在将u64
转换为usize
时可能会丢失信息(截断),因此不能存在From
转换。但是,usize
的大小始终保证为8位或更大,并且u8
到usize
From
转换将始终存在。
如前所述,从64位值转换为usize
可能会导致截断;当usize
为16或32位时,您可能会丢失数据。
TryFrom
trait涵盖了Fallable转换,可在Rust 1.34中获得:
use std::convert::TryFrom;
fn main() {
let a: u64 = 5;
let b = a as usize;
let b = usize::try_from(a);
}
也可以看看: