【问题标题】:Why is Rust's usize to u128 conversion considered failable?为什么 Rust 的 usize 到 u128 转换被认为是失败的?
【发布时间】:2020-10-31 02:04:02
【问题描述】:

看看:

use std::convert::{From, TryFrom};

fn main() {
  let size: usize = 42;
  let good: u128  = u128::try_from(size).unwrap(); // works fine
  let bad:  u128  = u128::from(size);              // doesn't compile!
}

据我所知,usize 是一个整数类型,它们永远不会超过 128 位。因此,我认为usize -> u128 转换不会失败。那么,为什么u128 不实现From<usize>

更新:Rust 的 documentation 说:

From T for U 意味着 Into U for T

虽然usize -> u128 看起来不错,但u128 -> usize 却不行。好的,但是为什么不为usize 实现Into<u128> 呢?

【问题讨论】:

  • usize 是指针的大小。 理论上你可以拥有一个地址空间需要超过 128 位来寻址的系统......总有一天。未来的证明? ;-)
  • “From T for U 意味着 Into U for T”在这种情况下,这意味着 usize -> u128u128 <- usize 都可以。它没有提到u128 -> usize

标签: error-handling rust type-conversion size unsigned


【解决方案1】:

虽然 usize -> u128 看起来不错,但 u128 -> usize 却不行。好的,但是为什么不为 usize 实现 Into 呢?

因为就 Rust 而言,虽然可以保证 usize 始终至少为 16 位,但不能保证始终最多为 64 位。

它似乎不太可能有用,但从技术上讲,没有什么可以排除 256 位指针,而且由于 usize 保证是指针大小的,它会使 usize -> u128 转换失败。

【讨论】:

  • 如果目标平台使用率仅为
  • 不,使核心 stdlib 特征“有条件地定义”不是一件正常的事情,至少对于标准库而言。标准库的正常做法是定义特定于平台的扩展特征,这里不相关。
  • 我的方法似乎比没有为所有平台定义特征要好得多,而实际上它目前可以在所有支持的平台上定义。是否有先例并不重要。
  • “更方便”并不意味着“更好”。先例实际上很重要,核心特征的消失是一项重大的政策变化,而不是无害的意见分歧。另请参阅:#37423、#70460
【解决方案2】:

From trait的文档说

注意:这个特性不能失败。如果转换失败,请使用 TryFrom。

由于您不知道 usize 是否可以保存 u16/u32/u64/u128 值(取决于您的编译目标),所有这些原始类型都实现 TryFrom 而不是 From。

在 Rust 文档中,implies 表示当你有一个类型实现了From 时,编译器会免费给你一个Into(注意,反之则不然)。同样的想法适用于TryFromTryInto。所以下面的代码将按预期工作。

use std::convert::{TryFrom,TryInto};

fn main() {
  let size: usize = 42;
  let good: u128  = u128::try_from(size).unwrap();
  let doublegood:usize = good.try_into().unwrap();
}

【讨论】:

  • 你是对的,但请检查更新后的帖子:usize 为什么不实现Into<u128>?我相信这并不意味着From(这将是不安全的)或其他任何东西。
  • @passing_through 相信它的设计是一致的,因为在今天的硬件中不能保证从 usize 到 u32、u16 和 u8 的转换。 Rust 面向未来,我们可能会看到有一天会在 PC 上安装 128 位或 256 位 CPU。如果那一天真的来了,那么从 usize 到 u128 的转换也不安全。因此,如果 rust 今天实现了 Into,则必须将其更改为 TryInto,任何依赖此功能的程序都将面临恐慌或无法完全运行的风险。此外,我们已经有了一个整洁的 as 来进行不安全的转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-15
  • 2012-05-11
  • 1970-01-01
相关资源
最近更新 更多