我想转换一个 usize
将变量键入 u32
Rust 中的类型变量。我知道 usize
变量可能包含大于 2^32 的值,在这种情况下转换应该会失败。我正在尝试使用 TryFrom
执行转换的特征。
这是一个简单的示例(Nightly Rust,Playground):
#![feature(try_from)]
use std::convert::TryFrom;
fn main() {
let a: usize = 0x100;
let res = u32::try_from(a);
println!("res = {:?}", res);
}
代码没有编译,编译错误如下:
error[E0277]: the trait bound `u32: std::convert::From<usize>` is not satisfied
--> src/main.rs:6:15
|
6 | let res = u32::try_from(a);
| ^^^^^^^^^^^^^ the trait `std::convert::From<usize>` is not implemented for `u32`
|
= help: the following implementations were found:
<u32 as std::convert::From<std::net::Ipv4Addr>>
<u32 as std::convert::From<u8>>
<u32 as std::convert::From<char>>
<u32 as std::convert::From<u16>>
= note: required because of the requirements on the impl of `std::convert::TryFrom<usize>` for `u32`
我从编译错误中推断出 TryFrom<usize>
对于 u32
依赖于 From<usize>
对于 u32
,这对我来说似乎有些奇怪。
有没有其他方法可以利用 TryFrom
从 usize
转换至 u32
?如果没有,是否还有其他惯用的方法来执行此转换?
我知道我可以使用 as
关键字,但如果转换出现问题,它不会通知我。此外,我认为我可以编写自己的函数来进行转换,但如果 Rust 没有一些惯用的方法来进行这种转换,我会感到很惊讶。 usize
和 u32
毕竟是两种基本类型。
最佳答案
自创建此答案以来,it was decided执行 TryFrom<usize>
无论当前平台如何,始终允许失败的可能性。原始代码现在可以在 Rust 1.34 中成功编译。
原始答案
having
TryFrom<usize>
foru32
is dependent on havingFrom<usize>
foru32
, which seems somewhat strange to me
这是因为有一个全面实现 TryFrom
对于任何实现 From
的东西:
impl<T, U> TryFrom<U> for T
where
T: From<U>,
{
type Error = !;
}
正如您所提到的,由于 Rust 支持原生整数长度为 16、32 或 64 位的平台,因此有这样一个 From
的实现。/Into
在其中一些平台上不会是无损的。
发生此错误是因为没有直接执行 TryFrom
/TryInto
对于这些类型。这是因为这些特征的用户更喜欢在适合平台的情况下实现绝对可靠(type Error = !
)。
有一个单独的tracking issue 49415专门决定这个问题。
I think that I can write my own function that does the conversion
是的,那是你应该做的。类似于这段未经测试的代码:
use std::u32;
struct SomeError;
// usize is a u16 or u32, which always fits in a u32
#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
fn my_thing(a: usize) -> Result<u32, SomeError> {
Ok(a as u32)
}
// usize is a u64, which might be too big
#[cfg(target_pointer_width = "64")]
fn my_thing(a: usize) -> Result<u32, SomeError> {
if a > u32::MAX as usize {
Err(SomeError)
} else {
Ok(a as u32)
}
}
I would be surprised if Rust doesn't have some idiomatic way to do this conversion.
usize
andu32
are two basic types, after all.
问题是 usize
并不是真正的“基本”类型,因为它会根据目标平台改变大小。获得正确的、高性能的和人体工程学并不容易。
关于rust - 如何使用 TryFrom 将 usize 转换为 u32?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49591393/