生成随机值
生成随机数
通过rand::thread_rng
,在随机数生成器rand::Rng
的帮助下,生成随机数。每个线程都有一个初始化的生成器。整数在该类型的范围(最大值 ~ 最小值)内,均匀分布,还有,浮点数是从 0 到 1,但不包括 1 的 均匀分布。
extern crate rand; 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
)生成随机值。
extern crate rand; 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
可以用来获得均匀分布的值。下面的代码是相同作用,但是当在相同范围内,重复生成数字时可能更快。
extern crate rand; 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; } } }
生成给定分布的随机数
默认情况下,随机数有均匀(Uniform) 分布。要使用其他(概率/类型的)分布生成数字,您需要实例化一个分布(distribution),然后用分布下的Distribution::sample
方法,在随机数生成器rand::Rng
的帮助下,进行采样。
关于可用分布的文档,在此。下面是,一个使用Normal
分布的的例子。
extern crate rand; use rand::distributions::{Normal, Distribution}; fn main() { let mut rng = rand::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) }
生成自定义类型的随机值
随机生成一个元组(i32, bool, f64)
,和用户定义类型的变量Point
。在 Point
类型之上,对Standard
实现Distribution
trait,为了(Point
)允许随机生成(gen
)。
这里,用得是,具象化泛型类型。
extern crate rand; use rand::Rng; use rand::distributions::{Distribution, Standard}; #[derive(Debug)] struct Point { x: i32, y: i32, } // 把 泛型 具象化为 Point, (定义实现) 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(); let rand_tuple = rng.gen::<(i32, bool, f64)>(); let rand_point: Point = rng.gen(); // 主要是 : Point,类型标签,让编译器知道 (调用上面的实现定义) println!("Random tuple: {:?}", rand_tuple); println!("Random Point: {:?}", rand_point); }
从一组字母+数字的字符,创建随机密码
随机生成,给定长度的 ASCII 字符串,字符范围是A-Z, a-z, 0-9
,运用Alphanumeric
(字母+数字)样品。
extern crate rand; use rand::{thread_rng, Rng}; use rand::distributions::Alphanumeric; fn main() { let rand_string: String = thread_rng() .sample_iter(&Alphanumeric) .take(30) .collect(); println!("{}", rand_string); }
从一组用户定义的字符,创建随机密码
使用用户自定义的字节字符串,随机生成给定长度的 ASCII 字符串,运用gen_range
。
extern crate rand; 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()); // 这是安全的,因为 `idx` 会在 `CHARSET` 的范围内。 char::from(unsafe { *CHARSET.get_unchecked(idx) }) // 来自用户的所有输入,最好都定义为不安全的。 }) .collect(); println!("{:?}", password); }