Rust生成隨機(jī)數(shù)的項(xiàng)目實(shí)踐
Rust標(biāo)準(zhǔn)庫(kù)中并沒(méi)有隨機(jī)數(shù)生成器,想要實(shí)現(xiàn)此類功能,你需要自行設(shè)計(jì)(純Rust或FFI到C),或者使用第三方包。
一個(gè)常見(jiàn)的解決方案是使用rand包,該項(xiàng)目基于Apache-2.0 和 MIT協(xié)議開(kāi)源,且擁有完備的文檔:
rust-random/rand: A Rust library for random number generation. (github.com)
0x00 | 在Cargo中導(dǎo)入
在Cargo.toml的[dependencies]下加入以下內(nèi)容即可:
rand = "*"
整個(gè)文件看起來(lái)會(huì)象是這樣:
[package] name = "hello_world" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] rand = "*"
0x01 | 生成隨機(jī)數(shù)
rand包提供了rand::Rng以生成隨機(jī)數(shù),這是一個(gè)隨機(jī)數(shù)生成器,它的使用是這樣的:
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let i: i32 = rng.gen();
let f: f32 = rng.gen();
println!("i={},f={}",i,f);
println!("random u8: {}",rng.gen::<u8>());
println!("random u32: {}",rng.gen::<u32>());
}
0x02 | 給定范圍生成隨機(jī)數(shù)
Rng::gen_range函數(shù)能夠在一個(gè)左閉又開(kāi)的區(qū)間內(nèi)生成隨機(jī)值:
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
println!("random integer: {}",rng.gen_range(0..10)); // 在[0,10)內(nèi)生成隨機(jī)整數(shù)
println!("random float: {}",rng.gen_range(0.0..10.0)); // 在[0,10)內(nèi)生成隨機(jī)浮點(diǎn)數(shù)
}
Rng::gen_range函數(shù)使用方便,但當(dāng)在相同范圍內(nèi)連續(xù)生成隨機(jī)數(shù)時(shí),其效果可能不盡人意。使用Uniform模塊可以得到符合均勻分布的值,以改善這一問(wèn)題。如下:
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!("Rool the die: {}",throw);
if throw == 6 {
break;
}
}
}
rand_distr是另一個(gè)包,它提供了基于rand包的數(shù)種分布模型,你可以在rand_distr - Rust (docs.rs)中找到相關(guān)信息。
以下是生成一個(gè)符合正態(tài)分布的隨機(jī)數(shù)的實(shí)列:
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!("spawn random num {} from N(2,6)",v);
Ok(())
}
0x03 | 給定類型生成隨機(jī)值
rand包可以直接生成一個(gè)隨機(jī)數(shù)元組:
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let rand_tuple = rng.gen::<(i32,bool,f64)>();
println!("Random tuple: {:?}",rand_tuple);
}
不過(guò)這種方法并不能指定隨機(jī)數(shù)的范圍,如果你真的需要限制其范圍,可能需要手動(dòng)生成每一個(gè)值。比如:
use rand::Rng;
fn main() {
let mut rng = rand::thread_rng();
let rand_tuple = (
rng.gen_range(0..100),
rng.gen::<bool>(),
rng.gen_range(0.0..1.0)
);
println!("Random tuple: {:?}", rand_tuple);
}
rand包也允許你通過(guò)為Standard類實(shí)現(xiàn)Distribution特性以將隨機(jī)數(shù)生成器集成到你的類中,如下:
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();
let rand_point: Point = rng.gen();
println!("Random Point: {:?}",rand_point);
}
通過(guò)修改sample函數(shù)可以進(jìn)一步指定范圍和分布模型。
0x04 | 生成隨機(jī)字符串
rand包可以生成一個(gè)指定長(zhǎng)度的隨機(jī)ASCII字符串,其樣本為A-Z,a-z,0-9。
一個(gè)生成包含30個(gè)ASCII字符的隨機(jī)字符串的例子如下:
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);
}
當(dāng)然,也可以從指定的字符集中生成隨機(jī)字符串:
use rand::Rng;
fn main() {
const CHARSET: &[u8] = b"123ABC?!";
let mut rng = rand::thread_rng();
let password: String = (0..30)
.map(|_| {
let idx = rng.gen_range(0..CHARSET.len());
CHARSET[idx] as char
})
.collect();
println!("{:?}", password);
}
參考:
生成隨機(jī)值 - Rust Cookbook 中文版 (rustwiki.org)
到此這篇關(guān)于Rust生成隨機(jī)數(shù)的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)Rust生成隨機(jī)數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust語(yǔ)言和C/C++區(qū)別對(duì)比,Rust和C語(yǔ)言哪個(gè)好
Rust具有與C語(yǔ)言相當(dāng)?shù)乃俣群蛢?nèi)存效率,但無(wú)需手動(dòng)內(nèi)存管理或垃圾回收,它擁有出色的工具支持、友好的編譯器和不斷發(fā)展的開(kāi)發(fā)者社區(qū),使用Rust能提升程序性能,最重要的是,對(duì)Python開(kāi)發(fā)者而言,Rust比C語(yǔ)言更容易學(xué)習(xí)2025-02-02
關(guān)于使用rust調(diào)用c++靜態(tài)庫(kù)并編譯nodejs包的問(wèn)題
這篇文章主要介紹了使用rust調(diào)用c++靜態(tài)庫(kù)并編譯nodejs包的問(wèn)題,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
Rust語(yǔ)言從入門到精通之Tokio的Channel深入理解
這篇文章主要為大家介紹了Rust語(yǔ)言從入門到精通之Tokio的Channel深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05

