使用 `rand::rngs::ThreadRng` 在 Rust 项目中依赖注入 SeedableRng

问题描述 投票:0回答:1

我在所有函数中都从常规的

&mut ThreadRng
开始,但它限制了依赖注入能力。有
SeedableRng
ofc,但是如何在最初是
ThreadRng
的地方使用它?

来自其他语言,我想在 fn 声明中指定一些接口,但是

&mut dyn Rng
不起作用,因为
Rng
不是对象安全的。

我最终得到的是到处经过

&mut StdRng
并且

let mut rng = match config.seed {
  Some(seed) => StdRng::seed_from_u64(seed),
  _ => StdRng::from_rng(rand::thread_rng()).unwrap_or(StdRng::from_entropy())
};

但是初始化 1

Rng
只是为了设置另一个
Rng

很尴尬

我还搜索了模式

StdRng::from_rng(rand::thread_rng())
,github 上只有 56 个样本,来自 141k 的使用
rand::thread_rng()

那么,接受 Rng 的 fn 的最佳签名是什么,以及使用可选种子进行初始化的最佳方法是什么?

附注我不关心 wasm/etc 运行时,它只是一个常规的服务器端应用程序

testing rust random dependency-injection
1个回答
0
投票

rand
文档有一些关于通用用法的信息:

由于

Rng: RngCore
并且每个
RngCore
都实现了
Rng
,因此无论我们使用
R: Rng
还是
R: RngCore

都没有区别

由此我们可以推断,在需要动态调度的情况下,我们可以使用对象安全

RngCore
来代替
Rng

use rand::{Rng, RngCore};
fn random(rng: &mut dyn RngCore) {
    println!("{}", rng.gen_range(0..9));
}

虽然更惯用的方法是使用静态调度,并且确实可以与

Rng
一起使用:

fn random(rng: &mut impl Rng) {
    println!("{}", rng.gen_range(0..9));
}
© www.soinside.com 2019 - 2024. All rights reserved.