此代码可以工作并打印" b":
fn main() {
let s = "abc";
let ch = s.chars().nth(1).unwrap();
println!("{}", ch);
}
另一方面,此代码会导致不匹配类型错误。
fn main() {
let s = "abc";
let n: u32 = 1;
let ch = s.chars().nth(n).unwrap();
println!("{}", ch);
}
error[E0308]: mismatched types
--> src/main.rs:5:28
|
5 | let ch = s.chars().nth(n).unwrap();
| ^ expected usize, found u32
出于某些外部原因,我必须将u32
类型用于变量n
。如何将u32
转换为usize
并在nth()
中使用它?
答案 0 :(得分:11)
as
运算符适用于所有数字类型:
let ch = s.chars().nth(n as usize).unwrap();
Rust会强制您投整整数,以确保您了解签名或溢出。
整数常量可以有一个类型后缀:
let n = 1u32;
但请注意,-1i32
等负面常量位于内部-
1i32
。
在没有显式类型规范的情况下声明的整数变量显示为{integer}
,并将从其中一个方法调用中正确推断。
答案 1 :(得分:2)
您可以做的最谨慎的操作是使用TryFrom
并在该值无法容纳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);
}
盲目使用as
,当在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
}
答案 2 :(得分:1)
当我们尝试编译您的代码时,我们有一个截然不同的答案,将数字1
替换为类型i32
的变量:
error[E0308]: mismatched types
--> src/main.rs:5:28
|
5 | let ch = s.chars().nth(n).unwrap();
| ^ expected usize, found i32
help: you can convert an `i32` to `usize` and panic if the converted value wouldn't fit
|
5 | let ch = s.chars().nth(n.try_into().unwrap()).unwrap();
|
这意味着现在编译器建议您使用利用特征TryInto
的n.try_into().unwrap()
,后者又依赖于TryFrom
并返回Result<T, T::Error>
。这就是为什么我们需要使用.unwrap()