5.1.1. 生成随机数
问题:
你想取得某个标量类型的随机数。
解决方案:
Rust 生态中,有一个比较成熟的随机值计算库 rand crate,提供了各类扩展 trait 和随机值计算的方法。在随机数生成器 rand::Rng
的帮助下,通过 rand::thread_rng
生成随机数。
并且,可以开启多个线程,每个线程都可以存在一个初始化的生成器。整数在其类型范围内均匀分布,浮点数是从 0 均匀分布到 1,但不包括 1。
以下实例代码引用自开源书籍项目《Cookin’ with Rust》,笔者在其基础上稍作修改。
use rand::Rng; // `RngCore` 上自动实现的扩展 trait,实现了高层次的泛型方法 fn main() { let mut rng = rand::thread_rng(); // 由系统创建的本地线程,是延迟初始化的随机数生成器 let n1: u8 = rng.gen(); // 返回一个支持标准分布的随机值 let n2: u16 = rng.gen(); println!(" u8 随机数: {}", n1); println!(" u16 随机数: {}", n2); println!(" u32 随机数: {}", rng.gen::<u32>()); println!(" i32 随机数: {}", rng.gen::<i32>()); println!(" float 随机数: {}", rng.gen::<f64>()); }
代码第 1 行,我们使用 use
关键字将 rand::Rng
引入作用域。rand::Rng
是在 RngCore
trait 上自动实现的扩展 trait,它实现了高层次的泛型方法。
代码第 4 行,由系统创建本地线程,作用为延迟初始化的随机数生成器。
代码第 6,7 行,均为返回支持标准分布的随机值,分别是 u8,u16 的无符号整型。
构建并运行后,结果大抵如下所示。
u8 随机数: 73
u16 随机数: 36982
u32 随机数: 2372946688
i32 随机数: 17124411
float 随机数: 0.8223380141339609
注:你的运行结果值和笔者运行结果不一定相同。
讨论:
rand::Rng
是 RngCore
上自动实现的扩展 trait,为抽样取值和其它便捷方法实现了高层次的泛型方法。
rand::thread_rng
是创建随机数生成器线程的函数。调用后,由系统创建延迟初始化的本地线程。随机生成器线程将用于方法链(method chaining)样式,如 thread_rng().gen::<i32>()
。或本地缓存,如 let mut rng = thread_rng();
。由 Default
trait 调用,等效于 ThreadRng::default()
。