编者注:此问题来自1.0之前的Rust版本,并引用了Rust 1.0中不存在的一些项目。答案仍然包含有价值的信息。
从({)1 usize
转换为u32
的惯用方法是什么?
例如,使用4294967295us as u32
进行投射并Rust 0.12 reference docs on type casting说
可以将数值转换为任何数字类型。原始指针值可以转换为任何整数类型或原始指针类型。任何其他演员表都不受支持,无法编译。
但是4294967296us as u32
会静默溢出并给出0的结果。
我发现ToPrimitive
和FromPrimitive
提供了很好的功能,例如to_u32() -> Option<u32>
,但它们被标记为不稳定:
#[unstable(feature = "core", reason = "trait is likely to be removed")]
在数字(和指针)类型之间进行转换的惯用(和安全)方式是什么?
依赖于平台的isize
/ usize
大小是我提出此问题的原因之一 - 原始方案是我想要从u32
转换为{{ 1}}所以我可以用usize
表示一棵树(例如Vec<u32>
,然后得到节点2的祖父将是let t = Vec![0u32, 0u32, 1u32]
),我想知道它会如何失败如果t[t[2us] as usize]
小于32位。
答案 0 :(得分:17)
ToPrimitive
/ FromPrimitive
理想情况下,[{1]} [...]将全部删除,以支持使用类似C的枚举的更有原则的方式
与此同时,这些特征仍然存在于num crate:
中这里没问题。使用ToPrimitive
明确表示不会发生任何损失:
From
您可以选择使用fn example(v: i8) -> i32 {
i32::from(v) // or v.into()
}
,但建议您在不需要时使用它(见下文):
as
没有一种方法可以理解 - 你要问的是如何在一个空间中放置两个东西。一个很好的初步尝试是在值适合时使用fn example(v: i8) -> i32 {
v as i32
}
- Option
,否则使用Some
。然后,您可以根据需要使程序失败或替换默认值。
自Rust 1.34起,您可以使用TryFrom
:
None
在此之前,您必须自己编写类似的代码:
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
会无声地溢出并给出0
转换为较小的类型时,4294967296us as u32
只取数字的低位,忽略高位,包括符号:
as