当前位置: 首页 > 知识库问答 >
问题:

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

东门佐
2023-03-14

编者按:这个问题来自Rust 1.0之前的版本,引用了Rust 1.0中不存在的一些项目。答案仍然包含有价值的信息。

从(比如说)一个usize转换成u32的惯用方法是什么?

例如,使用4294967295us作为u32进行铸造,并且类型铸造上的Rust 0.12参考文件

数值可以转换为任何数值类型。原始指针值可以转换为任何整型或原始指针类型。不支持任何其他强制转换,并且将无法编译。

但是,4294967296us as u32将自动溢出并给出0的结果。

我发现了ToPrimitive和FromPrimitive提供了很好的函数,如to_u32()-

#[不稳定(feature=“core”,reason=“trait可能被删除”)]

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

isize/usize的平台相关大小是我问这个问题的原因之一-最初的场景是我想从u32转换为usize,这样我就可以在Vec中表示一棵树


共有1个答案

钱繁
2023-03-14

这里没有问题。使用\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

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

您可以选择将用作,但建议在不需要时避免使用它(见下文):

fn example(v: i8) -> i32 {
    v as i32
}

没有一种方法是有普遍意义的——你问的是如何在一个空间中放置两件东西。一个很好的初始尝试是在值合适时使用选项-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)
    }
}

但是,4294967296us as u32将自动溢出并给出0的结果

当转换为较小的类型时,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
}

另见:

  • 从::from和生锈的区别是什么?

RFC 369,Num改革,指出:

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

同时,这些特征在num板条箱中继续存在:

  • ToPrimitive
  • FromPrimitive
 类似资料:
  • 问题内容: 我有一个PHP网站,为了进行实时更新和聊天,我已经安装了Node.js,并且运行良好。 PHP和Node.js都可以访问相同的MySQL数据库。 但是问题是要验证已经登录到PHP站点的用户的身份。 我不想通过任何方式(无论是否使用REST)与PHP应用程序对话。因为对我来说,这将与使用Node.js的目的相违背,因为随后每个Node.js请求都将产生一个新的PHP页面请求。 我想要的是

  • 本文向大家介绍用Python将IP地址在整型和字符串之间轻松转换,包括了用Python将IP地址在整型和字符串之间轻松转换的使用技巧和注意事项,需要的朋友参考一下 前言 大家应该都有所体会,对于字符串型的IP存入数据库中,实在是个即浪费空间又浪费性能的家伙,所以可爱的人们想出来将IP转换为整型存储。MySQL中存在INET_ATON() 、INET_NTOA()函数进行IP整型和字符串之间的转换,

  • Go 语言中不能通过 数据类型(变量)的格式将数值类型转换为字符串,也不能通过,数据类型(变量)的格式将字符串转换为数值类型 package main import "fmt" func main() { var num1 int32 = 65 // 可以将整型强制转换, 但是会按照ASCII码表来转换 // 但是不推荐这样使用 var str1 string =

  • 我的MongoDB数据库中的文档有两个主要属性——标头和有效负载。我的POJO将标头保存为带有键字符串和值字符串的地图。但是,由于我设置的地图限制,我的标头地图中有一个时间戳字段被QueryDSL读取为字符串。 如何使用QueryDSL比较保存为字符串的时间戳值(Long)? 我是否应该创建标头以将键类型字符串映射到值类型 Object?如果是这种情况,当返回的路径现在是简单路径而不是允许更复杂比

  • 在Go中,复制切片是标准费用,如下所示: 在《铁锈》中,我找不到类似的替换方法。我想到的东西是这样的: 不幸的是,我遇到了无法解决的编译错误: 如何设置?有没有更好的复制切片的方法?