Rust生成随机数的项目实践

 更新时间:2024年03月14日 10:58:57   作者:IAKSH  
Rust标准库中并没有随机数生成器,常见的解决方案是使用rand包,本文主要介绍了Rust生成随机数的项目实践,具有一定的参考价值,感兴趣的可以了解一下

Rust标准库中并没有随机数生成器,想要实现此类功能,你需要自行设计(纯Rust或FFI到C),或者使用第三方包。
一个常见的解决方案是使用rand包,该项目基于Apache-2.0 和 MIT协议开源,且拥有完备的文档:
rust-random/rand: A Rust library for random number generation. (github.com)

0x00 | 在Cargo中导入

Cargo.toml[dependencies]下加入以下内容即可:

rand = "*"

整个文件看起来会象是这样:

[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 | 生成随机数

rand包提供了rand::Rng以生成随机数,这是一个随机数生成器,它的使用是这样的:

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 | 给定范围生成随机数

Rng::gen_range函数能够在一个左闭又开的区间内生成随机值:

use rand::Rng;

fn main() {
	let mut rng = rand::thread_rng();
	println!("random integer: {}",rng.gen_range(0..10)); // 在[0,10)内生成随机整数
	println!("random float: {}",rng.gen_range(0.0..10.0)); // 在[0,10)内生成随机浮点数
}

Rng::gen_range函数使用方便,但当在相同范围内连续生成随机数时,其效果可能不尽人意。使用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!("Rool the die: {}",throw);
		if throw == 6 {
			break;
		}
	}
}

rand_distr是另一个包,它提供了基于rand包的数种分布模型,你可以在rand_distr - Rust (docs.rs)中找到相关信息。
以下是生成一个符合正态分布的随机数的实列:

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 | 给定类型生成随机值

rand包可以直接生成一个随机数元组:

use rand::Rng;

fn main() {
	let mut rng = rand::thread_rng();
	let rand_tuple = rng.gen::<(i32,bool,f64)>();
	println!("Random tuple: {:?}",rand_tuple);
}

不过这种方法并不能指定随机数的范围,如果你真的需要限制其范围,可能需要手动生成每一个值。比如:

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包也允许你通过为Standard类实现Distribution特性以将随机数生成器集成到你的类中,如下:

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);
}

通过修改sample函数可以进一步指定范围和分布模型。

0x04 | 生成随机字符串

rand包可以生成一个指定长度的随机ASCII字符串,其样本为A-Z,a-z,0-9
一个生成包含30个ASCII字符的随机字符串的例子如下:

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);
}

当然,也可以从指定的字符集中生成随机字符串:

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);
}

参考:
生成随机值 - Rust Cookbook 中文版 (rustwiki.org)

到此这篇关于Rust生成随机数的项目实践的文章就介绍到这了,更多相关Rust生成随机数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Rust数据类型之结构体Struct的使用

    Rust数据类型之结构体Struct的使用

    结构体是Rust中非常强大和灵活的数据结构,可以用于组织和操作各种类型的数据,本文就来介绍一下Rust数据类型之结构体Struct的使用,感兴趣的可以了解一下
    2023-12-12
  • Rust标量类型的具体使用

    Rust标量类型的具体使用

    本文主要介绍了Rust标量类型的具体使用,其中包括整数类型、浮点类型、布尔类型以及字符类型,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Rust Postgres实例代码

    Rust Postgres实例代码

    Rust Postgres是一个纯Rust实现的PostgreSQL客户端库,本文主要介绍了Rust Postgres实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-05-05
  • Rust捕获全局panic并记录进程退出日志的方法

    Rust捕获全局panic并记录进程退出日志的方法

    本文提供了捕获全局panic并记录进程退出日志的方法,首先使用 panic::set_hook 注册异常处理及panic 触发异常,结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-04-04
  • Rust中的关联类型总结

    Rust中的关联类型总结

    关联类型是定义通用trait的一种机制。它允许在trait中定义一个或多个占位符类型,这些类型将在trait的实现中具体化。文中有详细示例代码供参考,需要的朋友可以阅读一下
    2023-05-05
  • 使用vscode配置Rust运行环境全过程

    使用vscode配置Rust运行环境全过程

    VS Code对Rust有着较完备的支持,这篇文章主要给大家介绍了关于使用vscode配置Rust运行环境的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • rust zip异步压缩与解压的代码详解

    rust zip异步压缩与解压的代码详解

    在使用actix-web框架的时候,如果使用zip解压任务将会占用一个工作线程,因为zip库是同步阻塞的,想用异步非阻塞需要用另一个库,下面介绍下rust zip异步压缩与解压的示例,感兴趣的朋友一起看看吧
    2024-04-04
  • Rust使用libloader调用动态链接库

    Rust使用libloader调用动态链接库

    这篇文章主要为大家介绍了Rust使用libloader调用动态链接库示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • rust延迟5秒锁屏的实现代码

    rust延迟5秒锁屏的实现代码

    这篇文章主要介绍了rust延迟5秒锁屏的实现代码,文中通过实例代码也介绍了rust计算程序运行时间的方法,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • rust 创建多线程web server的详细过程

    rust 创建多线程web server的详细过程

    web server 中主要的两个协议是 http 和 tcp,tcp 是底层协议,http 是构建在 tcp 之上的,本篇文章重点给大家介绍rust 创建多线程web server的详细过程,感兴趣的朋友跟随小编一起看看吧
    2023-11-11

最新评论