我想将一个usize
类型的变量转换为Rust中的u32
类型变量。我知道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>
的{{1}}取决于u32
的{{1}},这对我来说似乎有点奇怪。
我还有其他方法可以利用From<usize>
将u32
转换为TryFrom
吗?如果没有,是否还有其他惯用方法来执行此转换?
我知道我可以使用usize
关键字,但如果转换出现问题,则不会通知我。另外,我认为我可以编写自己的函数进行转换,但是如果Rust没有一些惯用的方法来进行转换,我会感到惊讶。毕竟,u32
和as
是两种基本类型。
答案 0 :(得分:8)
自创建此答案以来,it was decided使TryFrom<usize>
的实施始终允许失败的可能性,无论当前平台如何。原始代码现在在Rust 1.34中成功编译。
<{1}}TryFrom<usize>
u32
取决于From<usize>
u32
,这对我来说有点奇怪
这是因为对于实现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专门用于决定此问题。
我认为我可以编写自己的功能进行转换
是的,这就是你应该做的。像这段未经测试的代码:
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)
}
}
如果Rust没有一些惯用的方法来进行这种转换,我会感到惊讶。毕竟,
usize
和u32
是两种基本类型。
问题是usize
实际上不是“基本”类型,因为它会根据目标平台改变大小。要获得正确,高效的和符合人体工程学并非易事。