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中Cargo的使用详解

    Rust中Cargo的使用详解

    Cargo 是 Rust 的构建系统和包管理器,⼤多数 Rustacean 们使⽤ Cargo 来管理他们的 Rust 项⽬,因为它可以为你处理很多任务,⽐如构建代码、下载依赖库并编译这些库,这篇文章主要介绍了Rust中Cargo的使用,需要的朋友可以参考下
    2022-11-11
  • Rust语言中的哈希表

    Rust语言中的哈希表

    哈希表也是集合中的一种,也是最常用的集合形式,目前Rust语言核心部分没有对哈希表进行实现,是使用标准库提供的,这篇文章主要介绍了Rust语言之哈希表,需要的朋友可以参考下
    2024-02-02
  • RUST异步流处理方法详细讲解

    RUST异步流处理方法详细讲解

    这篇文章主要介绍了RUST异步流处理方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • 深入了解Rust中的枚举和模式匹配

    深入了解Rust中的枚举和模式匹配

    这篇文章主要为大家详细介绍了Rust中的枚举和模式匹配的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • 深入理解Rust中Cargo的使用

    深入理解Rust中Cargo的使用

    本文主要介绍了深入理解Rust中Cargo的使用,Cargo简化了项目的构建过程,提供了依赖项管理,以及一系列方便的工作流程工具,下面就来具体的介绍一下如何使用,感兴趣的可以了解一下
    2024-04-04
  • Rust语言和C/C++区别对比,Rust和C语言哪个好

    Rust语言和C/C++区别对比,Rust和C语言哪个好

    Rust具有与C语言相当的速度和内存效率,但无需手动内存管理或垃圾回收,它拥有出色的工具支持、友好的编译器和不断发展的开发者社区,使用Rust能提升程序性能,最重要的是,对Python开发者而言,Rust比C语言更容易学习
    2025-02-02
  • 关于使用rust调用c++静态库并编译nodejs包的问题

    关于使用rust调用c++静态库并编译nodejs包的问题

    这篇文章主要介绍了使用rust调用c++静态库并编译nodejs包的问题,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • 详解Rust中的方法

    详解Rust中的方法

    方法其实就是结构体的成员函数,在C语言中的结构体是没有成员函数的,但是Rust毕竟也是一门面向对象的编程语言,所以给结构体加上方法的特性很符合面向对象的特点,这篇文章主要介绍了Rust中的方法,需要的朋友可以参考下
    2022-10-10
  • Rust语言从入门到精通之Tokio的Channel深入理解

    Rust语言从入门到精通之Tokio的Channel深入理解

    这篇文章主要为大家介绍了Rust语言从入门到精通之Tokio的Channel深入理解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • Rust中into和from用法及区别介绍

    Rust中into和from用法及区别介绍

    这篇文章主要介绍了Rust中的 into和from使用及区别介绍,into和from是Rust语言中两个用于类型转换的函数,它们分别属于Into和From这两个trait,本文通过实例代码详细讲解,需要的朋友可以参考下
    2023-04-04

最新评论