Trait RngExt
pub trait RngExt: Rng {
// Provided methods
fn random<T>(&mut self) -> T
where StandardUniform: Distribution<T> { ... }
fn random_iter<T>(self) -> Iter<StandardUniform, Self, T>
where Self: Sized,
StandardUniform: Distribution<T> { ... }
fn random_range<T, R>(&mut self, range: R) -> T
where T: SampleUniform,
R: SampleRange<T> { ... }
fn random_bool(&mut self, p: f64) -> bool { ... }
fn random_ratio(&mut self, numerator: u32, denominator: u32) -> bool { ... }
fn sample<T, D>(&mut self, distr: D) -> T
where D: Distribution<T> { ... }
fn sample_iter<T, D>(self, distr: D) -> Iter<D, Self, T>
where D: Distribution<T>,
Self: Sized { ... }
fn fill<T>(&mut self, dest: &mut [T])
where T: Fill { ... }
}Expand description
User-level interface for RNGs
Rng is the dyn-safe implementation-level interface for Random
(Number) Generators. This trait, Rng, provides a user-level interface on
RNGs. It is implemented automatically for any R: Rng.
This trait must usually be brought into scope via use rand::RngExt; or
use rand::prelude::*;.
§Generic usage
The basic pattern is fn foo<R: Rng + ?Sized>(rng: &mut R). Some
things are worth noting here:
- Since
RngExt: Rngand everyRngExtimplementsRng, it makes no difference whether we useR: RngorR: RngExtforR: Sized. - Only
Rngis dyn safe, supporting&mut dyn RngandR: Rng + ?Sized.
An alternative pattern is possible: fn foo<R: Rng>(rng: R). This has some
trade-offs. It allows the argument to be consumed directly without a &mut;
also it still works directly
on references (including type-erased references). Unfortunately within the
function foo it is not known whether rng is a reference type or not,
hence many uses of rng require an extra reference, either explicitly
(distr.sample(&mut rng)) or implicitly (rng.random()); one may hope the
optimiser can remove redundant references later.
Example:
use rand::{Rng, RngExt};
fn foo<R: Rng + ?Sized>(rng: &mut R) -> f32 {
rng.random()
}
Provided Methods§
fn random<T>(&mut self) -> Twhere
StandardUniform: Distribution<T>,
fn random<T>(&mut self) -> Twhere
StandardUniform: Distribution<T>,
Return a random value via the StandardUniform distribution.
§Example
use rand::RngExt;
let mut rng = rand::rng();
let x: u32 = rng.random();
println!("{}", x);
println!("{:?}", rng.random::<(f64, bool)>());§Arrays and tuples
The rng.random() method is able to generate arrays
and tuples (up to 12 elements), so long as all element types can be
generated.
For arrays of integers, especially for those with small element types
(< 64 bit), it will likely be faster to instead use RngExt::fill,
though note that generated values will differ.
use rand::RngExt;
let mut rng = rand::rng();
let tuple: (u8, i32, char) = rng.random(); // arbitrary tuple support
let arr1: [f32; 32] = rng.random(); // array construction
let mut arr2 = [0u8; 128];
rng.fill(&mut arr2); // array fillfn random_iter<T>(self) -> Iter<StandardUniform, Self, T>where
Self: Sized,
StandardUniform: Distribution<T>,
fn random_iter<T>(self) -> Iter<StandardUniform, Self, T>where
Self: Sized,
StandardUniform: Distribution<T>,
Return an iterator over random variates
This is a just a wrapper over RngExt::sample_iter using
[distr::StandardUniform].
Note: this method consumes its argument. Use
(&mut rng).random_iter() to avoid consuming the RNG.
§Example
use rand::{rngs::SmallRng, RngExt, SeedableRng};
let rng = SmallRng::seed_from_u64(0);
let v: Vec<i32> = rng.random_iter().take(5).collect();
assert_eq!(v.len(), 5);fn random_range<T, R>(&mut self, range: R) -> Twhere
T: SampleUniform,
R: SampleRange<T>,
fn random_range<T, R>(&mut self, range: R) -> Twhere
T: SampleUniform,
R: SampleRange<T>,
Generate a random value in the given range.
This function is optimised for the case that only a single sample is
made from the given range. See also the Uniform distribution
type which may be faster if sampling from the same range repeatedly.
All types support low..high_exclusive and low..=high range syntax.
Unsigned integer types also support ..high_exclusive and ..=high syntax.
§Panics
Panics if the range is empty, or if high - low overflows for floats.
§Example
use rand::RngExt;
let mut rng = rand::rng();
// Exclusive range
let n: u32 = rng.random_range(..10);
println!("{}", n);
let m: f64 = rng.random_range(-40.0..1.3e5);
println!("{}", m);
// Inclusive range
let n: u32 = rng.random_range(..=10);
println!("{}", n);fn random_bool(&mut self, p: f64) -> bool
fn random_bool(&mut self, p: f64) -> bool
fn random_ratio(&mut self, numerator: u32, denominator: u32) -> bool
fn random_ratio(&mut self, numerator: u32, denominator: u32) -> bool
Return a bool with a probability of numerator/denominator of being
true.
That is, random_ratio(2, 3) has chance of 2 in 3, or about 67%, of
returning true. If numerator == denominator, then the returned value
is guaranteed to be true. If numerator == 0, then the returned
value is guaranteed to be false.
See also the Bernoulli distribution, which may be faster if
sampling from the same numerator and denominator repeatedly.
§Panics
If denominator == 0 or numerator > denominator.
§Example
use rand::RngExt;
let mut rng = rand::rng();
println!("{}", rng.random_ratio(2, 3));fn sample<T, D>(&mut self, distr: D) -> Twhere
D: Distribution<T>,
fn sample<T, D>(&mut self, distr: D) -> Twhere
D: Distribution<T>,
Sample a new value, using the given distribution.
§Example
use rand::RngExt;
use rand::distr::Uniform;
let mut rng = rand::rng();
let x = rng.sample(Uniform::new(10u32, 15).unwrap());
// Type annotation requires two types, the type and distribution; the
// distribution can be inferred.
let y = rng.sample::<u16, _>(Uniform::new(10, 15).unwrap());fn sample_iter<T, D>(self, distr: D) -> Iter<D, Self, T>where
D: Distribution<T>,
Self: Sized,
fn sample_iter<T, D>(self, distr: D) -> Iter<D, Self, T>where
D: Distribution<T>,
Self: Sized,
Create an iterator that generates values using the given distribution.
Note: this method consumes its arguments. Use
(&mut rng).sample_iter(..) to avoid consuming the RNG.
§Example
use rand::RngExt;
use rand::distr::{Alphanumeric, Uniform, StandardUniform};
let mut rng = rand::rng();
// Vec of 16 x f32:
let v: Vec<f32> = (&mut rng).sample_iter(StandardUniform).take(16).collect();
// String:
let s: String = (&mut rng).sample_iter(Alphanumeric)
.take(7)
.map(char::from)
.collect();
// Combined values
println!("{:?}", (&mut rng).sample_iter(StandardUniform).take(5)
.collect::<Vec<(f64, bool)>>());
// Dice-rolling:
let die_range = Uniform::new_inclusive(1, 6).unwrap();
let mut roll_die = (&mut rng).sample_iter(die_range);
while roll_die.next().unwrap() != 6 {
println!("Not a 6; rolling again!");
}fn fill<T>(&mut self, dest: &mut [T])where
T: Fill,
fn fill<T>(&mut self, dest: &mut [T])where
T: Fill,
Fill any type implementing [Fill] with random data
This method is implemented for types which may be safely reinterpreted
as an (aligned) [u8] slice then filled with random data. It is often
faster than using RngExt::random but not value-equivalent.
The distribution is expected to be uniform with portable results, but this cannot be guaranteed for third-party implementations.
§Example
use rand::RngExt;
let mut arr = [0i8; 20];
rand::rng().fill(&mut arr[..]);Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.