Types 如何习惯地在u32和usize之间转换?
此代码工作并打印“b”: 另一方面,此代码会导致类型不匹配错误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使
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
}