Rust 为什么从u64到usize的类型转换允许使用`as`而不是`from`?

Rust 为什么从u64到usize的类型转换允许使用`as`而不是`from`?,rust,type-conversion,numbers,Rust,Type Conversion,Numbers,使用“as”的第一个转换将编译,但使用“From”特性的第二个转换不会: fn main() { let a: u64 = 5; let b = a as usize; let b = usize::from(a); } 使用Rust 1.34.0,我得到以下错误: error[E0277]:未满足特性绑定'usize:std::convert::From' -->src/main.rs:4:13 | 4 |设b=usize::from(a); |^^^^^^^^^^^

使用“as”的第一个转换将编译,但使用“From”特性的第二个转换不会:

fn main() {
    let a: u64 = 5;
    let b = a as usize;
    let b = usize::from(a);
}
使用Rust 1.34.0,我得到以下错误:

error[E0277]:未满足特性绑定'usize:std::convert::From'
-->src/main.rs:4:13
|
4 |设b=usize::from(a);
|^^^^^^^^^^^特性“std::convert::From”未为“usize”实现`
|
=帮助:找到了以下实现:
=注意:`std::convert::From::From'需要`
当我将
u64
替换为
u8
时,不再有错误。从错误消息中,我了解到,Fromtrait只针对
u8
实现,而不针对其他整数类型


如果有一个很好的理由,那么为什么使用“as”的转换不应该也无法编译呢?

因为
转换与转换有着根本的不同<来自的代码>转换是“简单和安全的”,而
as
强制转换是纯粹的“安全的”。在考虑数字类型时,只有在保证输出相同的情况下,才会存在来自的转换,即不会丢失信息(不会截断或降低精度)<但是,代码>as强制转换没有此限制

引用文件

[
usize
]的大小是“引用内存中的任何位置需要多少字节。例如,在32位目标上,这是4字节,在64位目标上,这是8字节。”

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


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

如前所述,从64位值转换为
usize
可能会导致截断;当
usize
为16或32位时,可能会丢失数据

可错误转换包含在Rust 1.34中:

use std::convert::TryFrom;

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


基于这种理解,我尝试了
println!(“{}”,500u16作为u8)并获取244。我认为“安全”在这里的意思是,我们不能破坏记忆,但我们最终可能会得到一个完全错误的号码。由于我不太愿意从数学的角度称之为“安全”,因此我建议将“强制转换纯粹是“安全的”替换为“强制转换仅是“内存安全的”,但可能会改变值”,或者在您的答案中如此。这样,未来的读者将对他们仍然可能创建的潜在bug发出更强烈的警告,并避免错误的“安全感”。“不安全操作是那些可能违反Rust静态语义的内存安全保证的操作。”@kazemakase谢谢,这就是我想说的。我会编辑答案。但令人惊讶的是,你(目前)不能(从另一个方向)使用
TryFrom