Types 如何习惯地在u32和usize之间转换?

Types 如何习惯地在u32和usize之间转换?,types,rust,type-conversion,Types,Rust,Type Conversion,此代码工作并打印“b”: 另一方面,此代码会导致类型不匹配错误 fn main() { let s = "abc"; let n: u32 = 1; let ch = s.chars().nth(n).unwrap(); println!("{}", ch); } 错误[E0308]:类型不匹配 -->src/main.rs:5:28 | 5 |设ch=s.chars().n(n).展开(); |^应为usize,找到u32 由于某些外部原因,我必须为变量n使

此代码工作并打印“b”:

另一方面,此代码会导致类型不匹配错误

fn main() {
    let s = "abc";
    let n: u32 = 1;
    let ch = s.chars().nth(n).unwrap();
    println!("{}", ch);
}
错误[E0308]:类型不匹配
-->src/main.rs:5:28
|
5 |设ch=s.chars().n(n).展开();
|^应为usize,找到u32

由于某些外部原因,我必须为变量
n
使用
u32
类型。如何将
u32
转换为
usize
并在
nth()
中使用它?

as运算符适用于所有数字类型:

let ch = s.chars().nth(n as usize).unwrap();
锈蚀迫使您强制转换整数,以确保您知道符号性或溢出

整型常量可以有一个类型后缀:

let n = 1u32;
但是,请注意,负常量,例如
-1i32
在内部是
-
1i32


在没有显式类型规范的情况下声明的整数变量显示为
{Integer}
,并将从其中一个方法调用中正确推断出来。

您可以做的最谨慎的事情是在值无法放入
usize
时使用并惊慌失措:

use std::convert::TryFrom;

fn main() {
    let s = "abc";
    let n: u32 = 1;
    let n_us = usize::try_from(n).unwrap();
    let ch = s.chars().nth(n_us).unwrap();
    println!("{}", ch);
}
如果盲目地将
用作
,那么在
usize
小于32位的平台上运行时,您的代码将以神秘的方式失败。例如,一些微控制器使用16位整数作为本机大小:

fn main() {
    let n: u32 = 0x1_FF_FF;
    // Pretend that `usize` is 16-bit
    let n_us: u16 = n as u16;
    
    println!("{}, {}", n, n_us); // 131071, 65535
}

有关超出
u32
usize
的更广泛的数字转换类型,请参阅。

当我们尝试编译您的代码时,我们现在有了一个非常不同的答案,将数字
1
替换为类型为
i32
的变量:

错误[E0308]:类型不匹配
-->src/main.rs:5:28
|
5 |设ch=s.chars().n(n).展开();
|^应使用,找到i32
帮助:您可以将'i32'转换为'usize',如果转换的值不合适,则会出现恐慌
|
5 |让ch=s.chars().nth(n.try_into().unwrap()).unwrap();
|    
这意味着现在编译器建议您使用
n.try_into().unwrap()
,它利用了特性,该特性反过来依赖于
TryFrom
,并返回一个
结果。这就是为什么我们需要使用
.unwrap()


这一点已经被an有效地涵盖了,因为
TryFrom
/
TryInto
是彼此的镜像。将
usize
转换为
u32
,或将其转换为
u32
的一些常见用例是什么?为了保护盲目复制和粘贴此答案的人:我认为@Shepmaster()的答案应该是“被接受的”回答。有人可能会在这里偶然发现这个答案,认为使用
as
可以保存数值转换,但事实并非如此。我认为在使用
TryFrom
之前,对于某些情况,开发人员也可以使用
From
特性(例如
u32::From(n)
。如果在Rust编译器中未实现强制转换,则在编译时会出现错误。但是:据我所知,
isize
usize
特征仅针对u8和u16实现,而未根据平台进行检查(请参阅和)。这可能是8位微控制器的问题(不确定Rust是否支持它们)@obraunsdorf链接到一个现有的答案,谢谢。
fn main() {
    let n: u32 = 0x1_FF_FF;
    // Pretend that `usize` is 16-bit
    let n_us: u16 = n as u16;
    
    println!("{}, {}", n, n_us); // 131071, 65535
}