gpt4 book ai didi

How to idiomatically convert between u32 and usize?(如何在u32和usize之间进行惯用转换?)

转载 作者:bug小助手 更新时间:2023-10-22 15:58:54 26 4
gpt4 key购买 nike



This code works and prints "b":

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



fn main() {
let s = "abc";
let ch = s.chars().nth(1).unwrap();
println!("{}", ch);
}


On the other hand, this code results in a mismatch type error.

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



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


For some external reason, I have to use the u32 type for variable n. How can I convert u32 to usize and use it in nth()?

由于一些外部原因,我不得不使用u32类型作为变量n。我如何将u32转换为usinze并在nth()中使用它?


更多回答
优秀答案推荐

The most cautious thing you can do is to use TryFrom and panic when the value cannot fit within a usize:

你能做的最谨慎的事情是使用TryFrom,并在值不能适应一个usinze时惊慌失措:


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);
}

By blindly using as, your code will fail in mysterious ways when run on a platform where usize is smaller than 32-bits. For example, some microcontrollers use 16-bit integers as the native size:

通过盲目使用as,当在usinze小于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
}

For broader types of numeric conversion beyond u32 <-> usize, refer to How do I convert between numeric types safely and idiomatically?.

有关u32<->usize之外更广泛的数字转换类型,请参阅如何安全且惯用地在数字类型之间转换?。


See also:

另请参阅:




The as operator works for all number types:

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



let ch = s.chars().nth(n as usize).unwrap();


Rust forces you to cast integers to make sure you're aware of signedness or overflows.

Rust强制您强制转换整数,以确保您知道有符号或溢出。



Integer constants can have a type suffix:

整数常量可以有类型后缀:



let n = 1u32;


However, note that negative constants, such as -1i32 is internally - 1i32.

但是,请注意,负常数(如-1i32)在内部是-1i32。



Integer variables declared without an explicit type specification are shown as {integer} and will be properly inferred from one of the method calls.

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



We now have a pretty different answer when we try to compile your code, replacing the number 1 with a variable of type i32:

现在,当我们试图编译代码时,我们有了一个完全不同的答案,将数字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();
|


It means that now the compiler recommends you to use n.try_into().unwrap() that makes use of the trait TryInto which in turn relies on TryFrom and returns a Result<T, T::Error>. That's why we need to extract the result with a .unwrap()

这意味着现在编译器建议您使用n.try_into().unwrap(),它利用了特性TryInto,该特性反过来依赖于TryFrom并返回Result 。这就是为什么我们需要使用.unwrap()提取结果



TryInto documentation

TryInto文档


更多回答

I think before using TryFrom, FOR SOME CASES, a developer could also use the From trait (e.g. u32::from(n). This should issue an error at compile-time if the cast is not implemented in the Rust-Compiler. HOWEVER: As far as i can see, the From trait for isize and usize is only implemented for u8 and u16 but are not checked depending on the platform (see doc.rust-lang.org/src/core/convert/num.rs.html#44 and doc.rust-lang.org/src/core/convert/num.rs.html#135). This could be an issue for 8-bit microcontrollers (not sure if Rust supports them)

我认为在使用TryFrom之前,在某些情况下,开发人员还可以使用From特性(例如u32::From(n))。如果未在Rust编译器中实现强制转换,则这将在编译时发出错误。HOWEVER:据我所见,isize和usize的From特性仅在u8和u16中实现,但根据平台的不同而未进行检查(请参阅doc.rust-lang.org/src/core/convert/num.rs.html#44和doc.rust-rang.org/src/core/convert/num.rs.html#135)。这可能是8位微控制器的问题(不确定rust是否支持它们)

@obraunsdorf linked to an existing answer that covers that, thanks.

@obraunsdorf联系到了一个现有的答案,谢谢。

To protect people who blindly copy&paste this answer: I think the answer from @Shepmaster (stackoverflow.com/a/55769098/1290383) should be the "accepted" answer. Someone might stumble across this answer here thinking that using as is save for numeric casts but it's not.

为了保护那些盲目复制粘贴这个答案的人:我认为@Shepmaster(stackoverflow.com/a/55769098/1290383)的答案应该是“公认的”答案。有些人可能会在这里偶然发现这个答案,认为使用as是对数值强制转换的保存,但事实并非如此。

casts between integertypes are safe in the sense they produve deterministic results. Tgose results may not be what you want, but the same applies to nost numeric operations.

整数类型之间的强制转换是安全的,因为它们会产生确定性的结果。Tgose结果可能不是您想要的,但nost数字运算也是如此。

This is effectively already covered by an existing answer, as TryFrom / TryInto are mirrors of each other.

这实际上已经被现有的答案所涵盖,因为TryFrom/TryInto是彼此的镜像。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com