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

时间:2017-12-13 05:45:37

标签: 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]: 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'的转换也不应该无法编译?

2 个答案:

答案 0 :(得分:10)

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位或更高,并且始终存在u8usize From转换。

答案 1 :(得分:1)

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

Fallable转换由TryFrom trait涵盖,可在Rust 1.34中找到:

use std::convert::TryFrom;

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

另见: