从(例如)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
}
也可以看看:
关于
ToPrimitive
/FromPrimitive
RFC 369, Num Reform, states:
同时,这些特征还存在于num crate中:
ToPrimitive
FromPrimitive
关于casting - 如何安全地和惯用地在数字类型之间转换?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28273169/