如何安全地和惯用地在数字类型之间进行转换?

Cas*_*par 38 casting numbers rust

从(比方说)a转换usize为a 的惯用方法是u32什么?

例如,铸造用4294967295us as u32作品和类型强制转换锈参考文档

数值可以转换为任何数字类型.原始指针值可以转换为任何整数类型或原始指针类型.任何其他强制转换都不受支持,无法编译.

但是4294967296us as u32会默默地溢出并给出0的结果.

我发现ToPrimitiveFromPrimitive提供了很好的功能ToPrimitive,但它们目前被标记为不稳定:

FromPrimitive

什么是在数字(和指针)类型之间转换的惯用(和安全)方式?

更新:to_u32() -> Option<u32>/的可变大小#[unstable(feature = "core", reason = "trait is likely to be removed")]是我问这个问题的一个原因 - 原始场景是我想转换isizeusize所以我可以代表一个树u32(例如usize,然后获得节点2的祖父将be Vec<u32>),我想知道如果let t = Vec![0u32, 0u32, 1u32]小于32位会如何失败.

She*_*ter 24

ToPrimitive

RFC状态:

理想情况下,ToPrimitive [...]将全部删除,以支持更有原则的方式使用类似C的枚举

所以看起来这个特性主要被视为C互操作的东西而不仅仅是尺寸变化.也许您可以提交另一个RFC或在用户论坛subredditIRC上询问是否保留它.

没有它的交易

让我们说FromPrimitive消失了.我建议检查是否弹出具有相同功能的板条箱.如果没有,您可以通过复制现有功能来创建一个.该功能的概要如下.

如果您从较小的类型转换为更大的类型,那么没有问题.你的问题实际上是围绕从较大的类型到较小的类型.

我认为没有一种方法可以理解 - 你要问的是如何在一个空间中放置两个东西.在某些情况下,这应该是一个致命的错误.在其他情况下,也许你有第二个代码路径.以下是如何使用MAX常量来检查:

fn example(v: i8) -> i32 {
    i32::from(v) // or v.into()
}
Run Code Online (Sandbox Code Playgroud)

但4294967296us作为u32将默默溢出并给出0的结果

为了澄清,ToPrimitive只需取数字的低位:

fn example(v: i8) -> i32 {
    v as i32
}
Run Code Online (Sandbox Code Playgroud)

  • @HutchMoore `as` 从不惊慌,据我所知。只有数学运算(例如加法、减法)才会出现恐慌。虽然通常被认为是调试/发布,但它是单独可控的。请参阅[如何在启用溢出检查的情况下编译和运行优化的 Rust 程序](/sf/ask/2383826861/) (2认同)