mirror of https://github.com/sunface/rust-course
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.0 KiB
5.0 KiB
生成随机值
生成随机数
使用 rand::thread_rng 可以获取一个随机数生成器 rand::Rng ,该生成器需要在每个线程都初始化一个。
整数的随机分布范围等于类型的取值范围,但是浮点数只分布在 [0, 1)
区间内。
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let n1: u8 = rng.gen();
let n2: u16 = rng.gen();
println!("Random u8: {}", n1);
println!("Random u16: {}", n2);
println!("Random u32: {}", rng.gen::<u32>());
println!("Random i32: {}", rng.gen::<i32>());
println!("Random float: {}", rng.gen::<f64>());
}
指定范围生成随机数
使用 Rng::gen_range 生成 [0, 10) 区间内的随机数( 右开区间,不包括 10
)。
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
println!("Integer: {}", rng.gen_range(0..10));
println!("Float: {}", rng.gen_range(0.0..10.0));
}
Uniform 可以用于生成均匀分布的随机数。当需要在同一个范围内重复生成随机数时,该方法虽然和之前的方法效果一样,但会更快一些。
use rand::distributions::{Distribution, Uniform};
fn main() {
let mut rng = rand::thread_rng();
let die = Uniform::from(1..7);
loop {
let throw = die.sample(&mut rng);
println!("Roll the die: {}", throw);
if throw == 6 {
break;
}
}
}
使用指定分布来生成随机数
默认情况下,rand
包使用均匀分布来生成随机数,而 rand_distr 包提供了其它类型的分布方式。
首先,你需要获取想要使用的分布的实例,然后在 rand::Rng 的帮助下使用 Distribution::sample 对该实例进行取样。
如果想要查询可用的分布列表,可以访问这里,下面的示例中我们将使用 Normal 分布:
use rand_distr::{Distribution, Normal, NormalError};
use rand::thread_rng;
fn main() -> Result<(), NormalError> {
let mut rng = thread_rng();
let normal = Normal::new(2.0, 3.0)?;
let v = normal.sample(&mut rng);
println!("{} is from a N(2, 9) distribution", v);
Ok(())
}
在自定义类型中生成随机值
使用 Distribution 特征包裹我们的自定义类型,并为 Standard 实现该特征,可以为自定义类型的指定字段生成随机数。
use rand::Rng;
use rand::distributions::{Distribution, Standard};
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
impl Distribution<Point> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Point {
let (rand_x, rand_y) = rng.gen();
Point {
x: rand_x,
y: rand_y,
}
}
}
fn main() {
let mut rng = rand::thread_rng();
// 生成一个随机的 Point
let rand_point: Point = rng.gen();
println!("Random Point: {:?}", rand_point);
// 通过类型暗示( hint )生成一个随机的元组
let rand_tuple = rng.gen::<(i32, bool, f64)>();
println!("Random tuple: {:?}", rand_tuple);
}
生成随机的字符串(A-Z, a-z, 0-9)
通过 Alphanumeric 采样来生成随机的 ASCII 字符串,包含从 A-Z, a-z, 0-9
的字符。
use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric;
fn main() {
let rand_string: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(30)
.map(char::from)
.collect();
println!("{}", rand_string);
}
生成随机的字符串( 用户指定 ASCII 字符 )
通过 gen_string 生成随机的 ASCII 字符串,包含用户指定的字符。
fn main() {
use rand::Rng;
const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz\
0123456789)(*&^%$#@!~";
const PASSWORD_LEN: usize = 30;
let mut rng = rand::thread_rng();
let password: String = (0..PASSWORD_LEN)
.map(|_| {
let idx = rng.gen_range(0..CHARSET.len());
CHARSET[idx] as char
})
.collect();
println!("{:?}", password);
}