从(例如)usize转换为u32的惯用方式是什么?
例如,使用4294967295us as u32进行转换有效,并且Rust 0.12 reference docs on type casting

但是4294967296us as u32会静默溢出并给出0的结果。
我发现 ToPrimitive FromPrimitive 提供了类似于to_u32() -> Option<u32>的不错的功能,但是它们被标记为不稳定的:

在数字(和指针)类型之间进行转换的惯用(安全)方法是什么?isize/usize依赖于平台的大小是我问这个问题的原因之一-原始方案是我想将u32转换为usize,以便可以用Vec<u32>表示一棵树(例如let t = Vec![0u32, 0u32, 1u32],然后得到一个宏-节点2的父节点将是t[t[2us] as usize]),我想知道如果usize小于32位将如何失败。

最佳答案

转换值

从完全适合另一种的类型

没问题使用 From 特征明确表明没有损失发生:

fn example(v: i8) -> i32 {
    i32::from(v) // or v.into()
}

您可以选择使用as,但是建议在不需要时避免使用它(请参见下文):
fn example(v: i8) -> i32 {
    v as i32
}

从不完全适合另一种的类型

没有一种方法具有一般意义-您要问的是如何在适合一个的空间中容纳两件事。一种很好的初始尝试是使用Option-值合适时使用Some,否则使用None。然后,您可以根据需要使程序失败或替换默认值。

从Rust 1.34开始,您可以使用 TryFrom :
use std::convert::TryFrom;

fn example(v: i32) -> Option<i8> {
    i8::try_from(v).ok()
}

在此之前,您必须自己编写类似的代码:
fn example(v: i32) -> Option<i8> {
    if v > std::i8::MAX as i32 {
        None
    } else {
        Some(v as i8)
    }
}
as的作用



转换为较小的类型时,as只是使用数字的低位,而忽略高位,包括符号:
fn main() {
    let a: u16 = 0x1234;
    let b: u8 = a as u8;
    println!("0x{:04x}, 0x{:02x}", a, b); // 0x1234, 0x34

    let a: i16 = -257;
    let b: u8 = a as u8;
    println!("0x{:02x}, 0x{:02x}", a, b); // 0xfeff, 0xff
}

也可以看看:
  • What is the difference between From::from and as in Rust?

  • 关于ToPrimitive/FromPrimitive
    RFC 369, Num Reform, states:



    同时,这些特征还存在于num crate中:
  • ToPrimitive
  • FromPrimitive
  • 关于casting - 如何安全地和惯用地在数字类型之间转换?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28273169/

    10-11 01:56