rand
是相当基础的Rust crate,是TRPL中第一个被介绍的非标准库。
本文是粗略的简介,想要详细了解可以看 The Rust Rand Book 以及 https://rust-random.github.io/rand 。
可以通过简单地调用 rand::random()
来获得一个随机值,这是一个泛型函数,需要能够推导出返回类型或者通过 turbo fish 语法显式指定:
1 | let v = rand::random::<(u8, f64)>(); |
更高级的用法涉及到随机数生成器(Random Number Generator, RNG),在 rand
中表示为 Rng
trait。这个类型的对象能不断生成一个个随机数。通过对生成的随机数进行一些处理,我们可以获得我们想要性质的随机数序列,比如符合某个随机分布、以某个概率生成随机数等。
大多数情况下rand::thread_rng
返回的随机数生成器就够用了。
这里介绍部分 Rng
提供的常用方法:
fn gen<T>(&mut self) -> T
生成一个T
类型的随机值fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T
生成区间[low, high)
中的随机值,这个特别常用,比如很容易就能生成一个 60 到 100 之间的及格分数:作为对比,在C语言中你得写1
2let mut rng = rand::thread_rng();
let passed_score : u32 = rng.gen_range(60, 101);rand() % (101-60) + 60
。fn gen_bool(&mut self, p: f64) -> bool
fn gen_ratio(&mut self, numerator: u32, denominator: u32) -> bool
这两个函数都是指定概率生成bool
值,gen_bool
用p
指定返回true
的概率,gen_ratio
返回true
的概率被指定为 $\frac{numerator}{denominator}$ 。
rand::seq
封装了关于序列(切片和迭代器)的随机方法。
对切片有 rand::seq::SliceRandom
trait,典型方法有:
fn choose<R: ?Sized>(&self, rng: &mut R) -> Option<&Self::Item>
随机选择切片中一个元素fn choose_multiple<R: ?Sized>( &self, rng: &mut R, amount: usize ) -> SliceChooseIter<Self, Self::Item>
无重复地以随机顺序随机选择切片中amount
个元素,返回符合Item=&T
的迭代器。fn shuffle<R: ?Sized>(&mut self, rng: &mut R)
随机重排整个切片中元素。
对迭代器有 rand::seq::IteratorRandom
trait。它的常用方法如下:
fn choose<R: ?Sized>(self, rng: &mut R) -> Option<Self::Item>
和SliceRandom::choose
类似。fn choose_multiple<R: ?Sized>( self, rng: &mut R, amount: usize ) -> Vec<Self::Item>
和SliceRandom::choose_multiple
类似,但是返回一个包含了所选元素的Vec
,而且不保证其中元素的顺序的随机性,如果需要保证随机顺序,要再shuffle
一次。
rand
还有 distribution (概率分布)的相关用法,这里就不说了。