4.5 升级到 0.9

原文链接: https://rust-random.github.io/book/update-0.9.html

下文提供了将代码从 rand 0.8 和 rand_distr 0.4 迁移到 rand 0.9 和 rand_distr 0.5 的说明。

以下是侧重于潜在破坏性更改的迁移指南。完整更改列表请参阅相关变更日志:

重命名的函数和方法

在 2024 edition 中,gen 是保留关键字。原始语法 r#gen() 很别扭,因此 rand::Rng 中的一些方法已重命名:

  • gen -> random
  • gen_range -> random_range
  • gen_bool -> random_bool
  • gen_ratio -> random_ratio

此外,rand::thread_rng() 已重命名为更简单的 rng()。

旧名称仍然存在但已弃用。

安全

在 #1514 中确定「rand 不是密码学库」。此更改澄清了:

  1. rand 库是没有任何法律约束保证的社区项目
  2. rand 库提供生成不可预测随机数的功能,但不提供任何高级密码学功能
  3. rand::rngs::OsRng 是无状态生成器,因此没有可泄露的状态,也不需要(重新)播种
  4. rand::rngs::ThreadRng 是自动播种的生成器,使用密码学强度的伪随机算法定期重新播种,但不保护其内存中的状态,特别是销毁时不会自动清零内存。此外,其设计是一种折衷:它被设计为「快速、相当安全的生成器」。

此外,ReseedingRng 和 ThreadRng 此前非常有限的 fork 保护已在 #1379 中移除。建议改为由导致 fork 的代码负责重新播种(更多细节参见 ThreadRng 文档):

1
2
3
4
5
6
7
fn do_fork() {
    let pid = unsafe { libc::fork() };
    if pid == 0 {
        // 在子进程中重新播种 ThreadRng:
        rand::rng().reseed();
    }
}

依赖

Rand crate 现在需要 rustc 版本 1.63.0 或更高。

对 getrandom 的依赖已升级到版本 0.3。 此版本 包含对某些平台的破坏性更改(WASM 尤其受影响)。

特性

特性标志:

  • serde1 已重命名为 serde
  • getrandom 已重命名为 os_rng
  • thread_rng 是新特性(默认启用),rng()(ThreadRng)需要
  • small_rng 现在默认启用
  • rand_chacha 不再是(隐式)特性;改用 std_rng

核心 trait

在 #1424 中,rand_core 添加了新 trait TryRngCore:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
pub trait TryRngCore {
    /// RNG 错误时返回的类型。
    type Error: fmt::Debug + fmt::Display;

    /// 返回下一个随机 `u32`。
    fn try_next_u32(&mut self) -> Result<u32, Self::Error>;
    /// 返回下一个随机 `u64`。
    fn try_next_u64(&mut self) -> Result<u64, Self::Error>;
    /// 用随机数据完全填充 `dest`。
    fn try_fill_bytes(&mut self, dst: &mut [u8]) -> Result<(), Self::Error>;

    // [省略的提供方法]
}

此 trait 对可能失败和不会失败的 RNG 泛型(后者使用 Infallible 错误类型),而 RngCore 现在仅表示不会失败的 RNG。

trait CryptoRng 现在是 RngCore 的子 trait。匹配的 trait TryCryptoRng 可用于标记 TryRngCore 的实现者具有密码学强度。

播种 RNG

trait SeedableRng 有一些更改:

  • type Seed 现在有额外边界:Clone 和 AsRef<[u8]>
  • fn from_rng 已重命名为 try_from_rng,同时添加了不会失败的变体作为新的 from_rng
  • fn from_entropy 已重命名为 from_os_rng,同时添加了新的可能失败变体 fn try_from_os_rng

生成器

ThreadRng 现在通过 rng() 访问(此前为 thread_rng())。

序列

旧 trait SliceRandom 已拆分为三个 trait:IndexedRandom、IndexedMutRandom 和 SliceRandom。这使 choose 功能可用于具有非连续存储的 Vec 类容器,尽管 shuffle 功能仍限于切片。

分布

模块 rand::distributions 已重命名为 rand::distr,以简洁并与 rand_distr 匹配。

distr 中的几个项也已重命名或移动:

  • 结构体 Standard -> StandardUniform
  • 结构体 Slice → slice::Choose
  • 结构体 EmptySlice → slice::Empty
  • Trait DistString → SampleString
  • 结构体 DistIter → Iter
  • 结构体 DistMap → Map
  • 结构体 WeightedIndex → weighted::WeightedIndex
  • 枚举 WeightedError → weighted::Error

rand_distr 中还有一些额外的重命名:

  • 结构体 weighted_alias::WeightedAliasIndex → weighted::WeightedAliasIndex
  • Trait weighted_alias::AliasableWeight → weighted::AliasableWeight

StandardUniform 分布不再支持采样 Option<T> 类型(对于任何 T)。

isize 和 usize 类型不再被 Fill、WeightedAliasIndex 或 StandardUniform 支持。Uniform 也不再支持 isize。usize 仍通过 UniformUsize 被 Uniform 支持,现在在 32 位和 64 位平台上具有可移植的结果。

Uniform 和 UniformSampler 的构造函数 fn new、fn new_inclusive 现在在无效输入时返回 Result 而非 panic。此外,Uniform 现在支持 TryFrom(而非 From)用于范围类型。

Nightly 特性

SIMD

SIMD 支持现在面向 std::simd。

可复现性

有关影响 rand 和 rand_distr 的可复现性破坏性更改的详情,请参阅 CHANGELOG.md 文件。

最后修改 August 23, 2026: 更新 (499855b16)