我在所有函数中都从常规的
&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 运行时,它只是一个常规的服务器端应用程序
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));
}