thread_rng() → rand::rng() (#1506)

- Rename `rand::thread_rng()` → `rand::rng()`
- Remove `thread_rng()` and `random()` from the prelude
This commit is contained in:
Diggory Hardy 2024-10-11 08:51:21 +01:00 committed by GitHub
parent 0fba9401c4
commit f5185d91fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
61 changed files with 174 additions and 167 deletions

View File

@ -28,6 +28,8 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.
- Implement `Distribution<u64>` for `Poisson<f64>` (#1498)
- Limit the maximal acceptable lambda for `Poisson` to solve (#1312) (#1498)
- Rename `Rng::gen_iter` to `random_iter` (#1500)
- Rename `rand::thread_rng()` to `rand::rng()`, and remove from the prelude (#1506)
- Remove `rand::random()` from the prelude (#1506)
## [0.9.0-alpha.1] - 2024-03-18
- Add the `Slice::num_choices` method to the Slice distribution (#1402)

View File

@ -11,7 +11,7 @@ Rand is a Rust library supporting random generators:
- A standard RNG trait: [`rand_core::RngCore`](https://docs.rs/rand_core/latest/rand_core/trait.RngCore.html)
- Fast implementations of the best-in-class [cryptographic](https://rust-random.github.io/book/guide-rngs.html#cryptographically-secure-pseudo-random-number-generators-csprngs) and
[non-cryptographic](https://rust-random.github.io/book/guide-rngs.html#basic-pseudo-random-number-generators-prngs) generators: [`rand::rngs`](https://docs.rs/rand/latest/rand/rngs/index.html), and more RNGs: [`rand_chacha`](https://docs.rs/rand_chacha), [`rand_xoshiro`](https://docs.rs/rand_xoshiro/), [`rand_pcg`](https://docs.rs/rand_pcg/), [rngs repo](https://github.com/rust-random/rngs/)
- [`rand::thread_rng`](https://docs.rs/rand/latest/rand/fn.thread_rng.html) is an asymtotically-fast, reasonably secure generator available on all `std` targets
- [`rand::rng`](https://docs.rs/rand/latest/rand/fn.rng.html) is an asymtotically-fast, reasonably secure generator available on all `std` targets
- Secure seeding via the [`getrandom` crate](https://crates.io/crates/getrandom)
Supporting random value generation and random processes:
@ -78,7 +78,7 @@ Rand is built with these features enabled by default:
- `alloc` (implied by `std`) enables functionality requiring an allocator
- `getrandom` (implied by `std`) is an optional dependency providing the code
behind `rngs::OsRng`
- `std_rng` enables inclusion of `StdRng`, `thread_rng`
- `std_rng` enables inclusion of `StdRng`, `ThreadRng`
Optionally, the following dependencies can be enabled:
@ -98,7 +98,7 @@ experimental `simd_support` feature.
Rand supports limited functionality in `no_std` mode (enabled via
`default-features = false`). In this case, `OsRng` and `from_os_rng` are
unavailable (unless `getrandom` is enabled), large parts of `seq` are
unavailable (unless `alloc` is enabled), and `thread_rng` is unavailable.
unavailable (unless `alloc` is enabled), and `ThreadRng` is unavailable.
## Portability and platform support

View File

@ -52,12 +52,12 @@ Explanation of exceptions:
- Jitter: `JitterRng` is used as an entropy source when the primary source
fails; this source may not be secure against side-channel attacks, see #699.
- ISAAC: the [ISAAC](https://burtleburtle.net/bob/rand/isaacafa.html) RNG used
to implement `thread_rng` is difficult to analyse and thus cannot provide
to implement `ThreadRng` is difficult to analyse and thus cannot provide
strong assertions of security.
## Known issues
In `rand` version 0.3 (0.3.18 and later), if `OsRng` fails, `thread_rng` is
In `rand` version 0.3 (0.3.18 and later), if `OsRng` fails, `ThreadRng` is
seeded from the system time in an insecure manner.
## Reporting a Vulnerability

View File

@ -26,7 +26,7 @@ pub fn bench(c: &mut Criterion) {
g.bench_function("u16_iter_repeat", |b| {
use core::iter;
let mut rng = Pcg64Mcg::from_rng(&mut thread_rng());
let mut rng = Pcg64Mcg::from_rng(&mut rand::rng());
b.iter(|| {
let v: Vec<u16> = iter::repeat(()).map(|()| rng.random()).take(512).collect();
v
@ -34,7 +34,7 @@ pub fn bench(c: &mut Criterion) {
});
g.bench_function("u16_sample_iter", |b| {
let mut rng = Pcg64Mcg::from_rng(&mut thread_rng());
let mut rng = Pcg64Mcg::from_rng(&mut rand::rng());
b.iter(|| {
let v: Vec<u16> = Standard.sample_iter(&mut rng).take(512).collect();
v
@ -42,7 +42,7 @@ pub fn bench(c: &mut Criterion) {
});
g.bench_function("u16_gen_array", |b| {
let mut rng = Pcg64Mcg::from_rng(&mut thread_rng());
let mut rng = Pcg64Mcg::from_rng(&mut rand::rng());
b.iter(|| {
let v: [u16; 512] = rng.random();
v
@ -50,7 +50,7 @@ pub fn bench(c: &mut Criterion) {
});
g.bench_function("u16_fill", |b| {
let mut rng = Pcg64Mcg::from_rng(&mut thread_rng());
let mut rng = Pcg64Mcg::from_rng(&mut rand::rng());
let mut buf = [0u16; 512];
b.iter(|| {
rng.fill(&mut buf[..]);
@ -60,7 +60,7 @@ pub fn bench(c: &mut Criterion) {
g.bench_function("u64_iter_repeat", |b| {
use core::iter;
let mut rng = Pcg64Mcg::from_rng(&mut thread_rng());
let mut rng = Pcg64Mcg::from_rng(&mut rand::rng());
b.iter(|| {
let v: Vec<u64> = iter::repeat(()).map(|()| rng.random()).take(128).collect();
v
@ -68,7 +68,7 @@ pub fn bench(c: &mut Criterion) {
});
g.bench_function("u64_sample_iter", |b| {
let mut rng = Pcg64Mcg::from_rng(&mut thread_rng());
let mut rng = Pcg64Mcg::from_rng(&mut rand::rng());
b.iter(|| {
let v: Vec<u64> = Standard.sample_iter(&mut rng).take(128).collect();
v
@ -76,7 +76,7 @@ pub fn bench(c: &mut Criterion) {
});
g.bench_function("u64_gen_array", |b| {
let mut rng = Pcg64Mcg::from_rng(&mut thread_rng());
let mut rng = Pcg64Mcg::from_rng(&mut rand::rng());
b.iter(|| {
let v: [u64; 128] = rng.random();
v
@ -84,7 +84,7 @@ pub fn bench(c: &mut Criterion) {
});
g.bench_function("u64_fill", |b| {
let mut rng = Pcg64Mcg::from_rng(&mut thread_rng());
let mut rng = Pcg64Mcg::from_rng(&mut rand::rng());
let mut buf = [0u64; 128];
b.iter(|| {
rng.fill(&mut buf[..]);

View File

@ -27,41 +27,41 @@ pub fn bench(c: &mut Criterion) {
g.measurement_time(core::time::Duration::from_millis(1000));
g.bench_function("standard", |b| {
let mut rng = Pcg32::from_rng(&mut thread_rng());
let mut rng = Pcg32::from_rng(&mut rand::rng());
b.iter(|| rng.sample::<bool, _>(rand::distr::Standard))
});
g.bench_function("const", |b| {
let mut rng = Pcg32::from_rng(&mut thread_rng());
let mut rng = Pcg32::from_rng(&mut rand::rng());
b.iter(|| rng.gen_bool(0.18))
});
g.bench_function("var", |b| {
let mut rng = Pcg32::from_rng(&mut thread_rng());
let mut rng = Pcg32::from_rng(&mut rand::rng());
let p = rng.random();
b.iter(|| rng.gen_bool(p))
});
g.bench_function("ratio_const", |b| {
let mut rng = Pcg32::from_rng(&mut thread_rng());
let mut rng = Pcg32::from_rng(&mut rand::rng());
b.iter(|| rng.gen_ratio(2, 3))
});
g.bench_function("ratio_var", |b| {
let mut rng = Pcg32::from_rng(&mut thread_rng());
let mut rng = Pcg32::from_rng(&mut rand::rng());
let d = rng.gen_range(1..=100);
let n = rng.gen_range(0..=d);
b.iter(|| rng.gen_ratio(n, d));
});
g.bench_function("bernoulli_const", |b| {
let mut rng = Pcg32::from_rng(&mut thread_rng());
let mut rng = Pcg32::from_rng(&mut rand::rng());
let d = Bernoulli::new(0.18).unwrap();
b.iter(|| rng.sample(d))
});
g.bench_function("bernoulli_var", |b| {
let mut rng = Pcg32::from_rng(&mut thread_rng());
let mut rng = Pcg32::from_rng(&mut rand::rng());
let p = rng.random();
let d = Bernoulli::new(p).unwrap();
b.iter(|| rng.sample(d))

View File

@ -50,7 +50,7 @@ pub fn gen_bytes(c: &mut Criterion) {
bench(&mut g, "std", StdRng::from_os_rng());
bench(&mut g, "small", SmallRng::from_thread_rng());
bench(&mut g, "os", UnwrapErr(OsRng));
bench(&mut g, "thread", thread_rng());
bench(&mut g, "thread", rand::rng());
g.finish()
}
@ -79,7 +79,7 @@ pub fn gen_u32(c: &mut Criterion) {
bench(&mut g, "std", StdRng::from_os_rng());
bench(&mut g, "small", SmallRng::from_thread_rng());
bench(&mut g, "os", UnwrapErr(OsRng));
bench(&mut g, "thread", thread_rng());
bench(&mut g, "thread", rand::rng());
g.finish()
}
@ -108,7 +108,7 @@ pub fn gen_u64(c: &mut Criterion) {
bench(&mut g, "std", StdRng::from_os_rng());
bench(&mut g, "small", SmallRng::from_thread_rng());
bench(&mut g, "os", UnwrapErr(OsRng));
bench(&mut g, "thread", thread_rng());
bench(&mut g, "thread", rand::rng());
g.finish()
}

View File

@ -20,7 +20,7 @@ criterion_main!(benches);
pub fn bench(c: &mut Criterion) {
c.bench_function("seq_slice_choose_1_of_100", |b| {
let mut rng = Pcg32::from_rng(&mut thread_rng());
let mut rng = Pcg32::from_rng(&mut rand::rng());
let mut buf = [0i32; 100];
rng.fill(&mut buf);
let x = black_box(&mut buf);
@ -32,7 +32,7 @@ pub fn bench(c: &mut Criterion) {
for (amount, len) in lens {
let name = format!("seq_slice_choose_multiple_{}_of_{}", amount, len);
c.bench_function(name.as_str(), |b| {
let mut rng = Pcg32::from_rng(&mut thread_rng());
let mut rng = Pcg32::from_rng(&mut rand::rng());
let mut buf = [0i32; 1000];
rng.fill(&mut buf);
let x = black_box(&buf[..len]);
@ -53,7 +53,7 @@ pub fn bench(c: &mut Criterion) {
}
c.bench_function("seq_iter_choose_multiple_10_of_100", |b| {
let mut rng = Pcg32::from_rng(&mut thread_rng());
let mut rng = Pcg32::from_rng(&mut rand::rng());
let mut buf = [0i32; 100];
rng.fill(&mut buf);
let x = black_box(&buf);
@ -61,7 +61,7 @@ pub fn bench(c: &mut Criterion) {
});
c.bench_function("seq_iter_choose_multiple_fill_10_of_100", |b| {
let mut rng = Pcg32::from_rng(&mut thread_rng());
let mut rng = Pcg32::from_rng(&mut rand::rng());
let mut buf = [0i32; 100];
rng.fill(&mut buf);
let x = black_box(&buf);

View File

@ -20,7 +20,7 @@ criterion_main!(benches);
pub fn bench(c: &mut Criterion) {
c.bench_function("seq_shuffle_100", |b| {
let mut rng = Pcg32::from_rng(&mut thread_rng());
let mut rng = Pcg32::from_rng(&mut rand::rng());
let mut buf = [0i32; 100];
rng.fill(&mut buf);
let x = black_box(&mut buf);

View File

@ -23,7 +23,7 @@ const N_RESAMPLES: usize = 10_000;
macro_rules! sample {
($R:ty, $T:ty, $U:ty, $g:expr) => {
$g.bench_function(BenchmarkId::new(stringify!($R), "single"), |b| {
let mut rng = <$R>::from_rng(&mut thread_rng());
let mut rng = <$R>::from_rng(&mut rand::rng());
let x = rng.random::<$U>();
let bits = (<$T>::BITS / 2);
let mask = (1 as $U).wrapping_neg() >> bits;
@ -35,7 +35,7 @@ macro_rules! sample {
});
$g.bench_function(BenchmarkId::new(stringify!($R), "distr"), |b| {
let mut rng = <$R>::from_rng(&mut thread_rng());
let mut rng = <$R>::from_rng(&mut rand::rng());
let x = rng.random::<$U>();
let bits = (<$T>::BITS / 2);
let mask = (1 as $U).wrapping_neg() >> bits;

View File

@ -27,7 +27,7 @@ const N_RESAMPLES: usize = 10_000;
macro_rules! single_random {
($R:ty, $T:ty, $g:expr) => {
$g.bench_function(BenchmarkId::new(stringify!($T), stringify!($R)), |b| {
let mut rng = <$R>::from_rng(&mut thread_rng());
let mut rng = <$R>::from_rng(&mut rand::rng());
let (mut low, mut high);
loop {
low = <$T>::from_bits(rng.random());
@ -63,7 +63,7 @@ fn single_random(c: &mut Criterion) {
macro_rules! distr_random {
($R:ty, $T:ty, $g:expr) => {
$g.bench_function(BenchmarkId::new(stringify!($T), stringify!($R)), |b| {
let mut rng = <$R>::from_rng(&mut thread_rng());
let mut rng = <$R>::from_rng(&mut rand::rng());
let dist = loop {
let low = <$T>::from_bits(rng.random());
let high = <$T>::from_bits(rng.random());

View File

@ -20,7 +20,7 @@ criterion_main!(benches);
pub fn bench(c: &mut Criterion) {
c.bench_function("weighted_index_creation", |b| {
let mut rng = rand::thread_rng();
let mut rng = rand::rng();
let weights = black_box([1u32, 2, 4, 0, 5, 1, 7, 1, 2, 3, 4, 5, 6, 7]);
b.iter(|| {
let distr = WeightedIndex::new(weights.to_vec()).unwrap();
@ -29,7 +29,7 @@ pub fn bench(c: &mut Criterion) {
});
c.bench_function("weighted_index_modification", |b| {
let mut rng = rand::thread_rng();
let mut rng = rand::rng();
let weights = black_box([1u32, 2, 3, 0, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7]);
let mut distr = WeightedIndex::new(weights.to_vec()).unwrap();
b.iter(|| {
@ -53,7 +53,7 @@ pub fn bench(c: &mut Criterion) {
c.bench_function(name.as_str(), |b| {
let length = black_box(length);
let amount = black_box(amount);
let mut rng = SmallRng::from_rng(&mut thread_rng());
let mut rng = SmallRng::from_rng(&mut rand::rng());
b.iter(|| sample_weighted(&mut rng, length, |idx| (1 + (idx % 100)) as u32, amount))
});
}

View File

@ -27,7 +27,7 @@ use rand::distr::{Distribution, Uniform};
fn main() {
let range = Uniform::new(-1.0f64, 1.0).unwrap();
let mut rng = rand::thread_rng();
let mut rng = rand::rng();
let total = 1_000_000;
let mut in_circle = 0;

View File

@ -77,7 +77,7 @@ fn main() {
// The estimation will be more accurate with more simulations
let num_simulations = 10000;
let mut rng = rand::thread_rng();
let mut rng = rand::rng();
let random_door = Uniform::new(0u32, 3).unwrap();
let (mut switch_wins, mut switch_losses) = (0, 0);

View File

@ -41,7 +41,7 @@
//! let rng = ChaCha12Rng::from_os_rng();
//! # let _: ChaCha12Rng = rng;
//! ```
//! 2. **From a master generator.** This could be [`rand::thread_rng`]
//! 2. **From a master generator.** This could be [`rand::rng`]
//! (effectively a fresh seed without the need for a syscall on each usage)
//! or a deterministic generator such as [`ChaCha20Rng`].
//! Beware that should a weak master generator be used, correlations may be
@ -74,7 +74,7 @@
//! [`RngCore`]: rand_core::RngCore
//! [`SeedableRng`]: rand_core::SeedableRng
//! [`SeedableRng::from_os_rng`]: rand_core::SeedableRng::from_os_rng
//! [`rand::thread_rng`]: https://docs.rs/rand/latest/rand/fn.thread_rng.html
//! [`rand::rng`]: https://docs.rs/rand/latest/rand/fn.rng.html
//! [`rand::Rng`]: https://docs.rs/rand/latest/rand/trait.Rng.html
#![doc(

View File

@ -487,7 +487,7 @@ pub trait SeedableRng: Sized {
///
/// In case the overhead of using [`getrandom`] to seed *many* PRNGs is an
/// issue, one may prefer to seed from a local PRNG, e.g.
/// `from_rng(thread_rng()).unwrap()`.
/// `from_rng(rand::rng()).unwrap()`.
///
/// # Panics
///
@ -508,7 +508,7 @@ pub trait SeedableRng: Sized {
///
/// In case the overhead of using [`getrandom`] to seed *many* PRNGs is an
/// issue, one may prefer to seed from a local PRNG, e.g.
/// `from_rng(&mut thread_rng()).unwrap()`.
/// `from_rng(&mut rand::rng()).unwrap()`.
///
/// [`getrandom`]: https://docs.rs/getrandom
#[cfg(feature = "getrandom")]

View File

@ -73,7 +73,7 @@ struct BC<N> {
/// use rand_distr::{Distribution, Beta};
///
/// let beta = Beta::new(2.0, 5.0).unwrap();
/// let v = beta.sample(&mut rand::thread_rng());
/// let v = beta.sample(&mut rand::rng());
/// println!("{} is from a Beta(2, 5) distribution", v);
/// ```
#[derive(Clone, Copy, Debug, PartialEq)]

View File

@ -40,7 +40,7 @@ use rand::Rng;
/// use rand_distr::{Binomial, Distribution};
///
/// let bin = Binomial::new(20, 0.3).unwrap();
/// let v = bin.sample(&mut rand::thread_rng());
/// let v = bin.sample(&mut rand::rng());
/// println!("{} is from a binomial distribution", v);
/// ```
#[derive(Clone, Copy, Debug, PartialEq)]

View File

@ -45,7 +45,7 @@ use rand::Rng;
/// use rand_distr::{Cauchy, Distribution};
///
/// let cau = Cauchy::new(2.0, 5.0).unwrap();
/// let v = cau.sample(&mut rand::thread_rng());
/// let v = cau.sample(&mut rand::rng());
/// println!("{} is from a Cauchy(2, 5) distribution", v);
/// ```
///

View File

@ -41,7 +41,7 @@ use serde::{Deserialize, Serialize};
/// use rand_distr::{ChiSquared, Distribution};
///
/// let chi = ChiSquared::new(11.0).unwrap();
/// let v = chi.sample(&mut rand::thread_rng());
/// let v = chi.sample(&mut rand::rng());
/// println!("{} is from a χ²(11) distribution", v)
/// ```
#[derive(Clone, Copy, Debug, PartialEq)]

View File

@ -211,7 +211,7 @@ where
/// use rand_distr::Dirichlet;
///
/// let dirichlet = Dirichlet::new([1.0, 2.0, 3.0]).unwrap();
/// let samples = dirichlet.sample(&mut rand::thread_rng());
/// let samples = dirichlet.sample(&mut rand::rng());
/// println!("{:?} is from a Dirichlet([1.0, 2.0, 3.0]) distribution", samples);
/// ```
#[cfg_attr(feature = "serde_with", serde_as)]

View File

@ -34,7 +34,7 @@ use rand::Rng;
/// use rand::prelude::*;
/// use rand_distr::Exp1;
///
/// let val: f64 = thread_rng().sample(Exp1);
/// let val: f64 = rand::rng().sample(Exp1);
/// println!("{}", val);
/// ```
///
@ -116,7 +116,7 @@ impl Distribution<f64> for Exp1 {
/// use rand_distr::{Exp, Distribution};
///
/// let exp = Exp::new(2.0).unwrap();
/// let v = exp.sample(&mut rand::thread_rng());
/// let v = exp.sample(&mut rand::rng());
/// println!("{} is from a Exp(2) distribution", v);
/// ```
#[derive(Clone, Copy, Debug, PartialEq)]

View File

@ -34,7 +34,7 @@ use serde::{Deserialize, Serialize};
/// use rand_distr::{FisherF, Distribution};
///
/// let f = FisherF::new(2.0, 32.0).unwrap();
/// let v = f.sample(&mut rand::thread_rng());
/// let v = f.sample(&mut rand::rng());
/// println!("{} is from an F(2, 32) distribution", v)
/// ```
#[derive(Clone, Copy, Debug, PartialEq)]

View File

@ -40,7 +40,7 @@ use rand::Rng;
/// use rand::prelude::*;
/// use rand_distr::Frechet;
///
/// let val: f64 = thread_rng().sample(Frechet::new(0.0, 1.0, 1.0).unwrap());
/// let val: f64 = rand::rng().sample(Frechet::new(0.0, 1.0, 1.0).unwrap());
/// println!("{}", val);
/// ```
#[derive(Clone, Copy, Debug, PartialEq)]

View File

@ -47,7 +47,7 @@ use serde::{Deserialize, Serialize};
/// use rand_distr::{Distribution, Gamma};
///
/// let gamma = Gamma::new(2.0, 5.0).unwrap();
/// let v = gamma.sample(&mut rand::thread_rng());
/// let v = gamma.sample(&mut rand::rng());
/// println!("{} is from a Gamma(2, 5) distribution", v);
/// ```
///

View File

@ -35,7 +35,7 @@ use rand::Rng;
/// use rand_distr::{Geometric, Distribution};
///
/// let geo = Geometric::new(0.25).unwrap();
/// let v = geo.sample(&mut rand::thread_rng());
/// let v = geo.sample(&mut rand::rng());
/// println!("{} is from a Geometric(0.25) distribution", v);
/// ```
#[derive(Copy, Clone, Debug, PartialEq)]
@ -168,7 +168,7 @@ impl Distribution<u64> for Geometric {
/// use rand::prelude::*;
/// use rand_distr::StandardGeometric;
///
/// let v = StandardGeometric.sample(&mut thread_rng());
/// let v = StandardGeometric.sample(&mut rand::rng());
/// println!("{} is from a Geometric(0.5) distribution", v);
/// ```
///

View File

@ -38,7 +38,7 @@ use rand::Rng;
/// use rand::prelude::*;
/// use rand_distr::Gumbel;
///
/// let val: f64 = thread_rng().sample(Gumbel::new(0.0, 1.0).unwrap());
/// let val: f64 = rand::rng().sample(Gumbel::new(0.0, 1.0).unwrap());
/// println!("{}", val);
/// ```
#[derive(Clone, Copy, Debug, PartialEq)]

View File

@ -54,7 +54,7 @@ enum SamplingMethod {
/// use rand_distr::{Distribution, Hypergeometric};
///
/// let hypergeo = Hypergeometric::new(60, 24, 7).unwrap();
/// let v = hypergeo.sample(&mut rand::thread_rng());
/// let v = hypergeo.sample(&mut rand::rng());
/// println!("{} is from a hypergeometric distribution", v);
/// ```
#[derive(Copy, Clone, Debug, PartialEq)]

View File

@ -44,7 +44,7 @@ impl std::error::Error for Error {}
/// use rand_distr::{InverseGaussian, Distribution};
///
/// let inv_gauss = InverseGaussian::new(1.0, 2.0).unwrap();
/// let v = inv_gauss.sample(&mut rand::thread_rng());
/// let v = inv_gauss.sample(&mut rand::rng());
/// println!("{} is from a inverse Gaussian(1, 2) distribution", v);
/// ```
#[derive(Debug, Clone, Copy, PartialEq)]

View File

@ -32,7 +32,7 @@ use rand::Rng;
/// use rand::prelude::*;
/// use rand_distr::StandardNormal;
///
/// let val: f64 = thread_rng().sample(StandardNormal);
/// let val: f64 = rand::rng().sample(StandardNormal);
/// println!("{}", val);
/// ```
///
@ -130,7 +130,7 @@ impl Distribution<f64> for StandardNormal {
///
/// // mean 2, standard deviation 3
/// let normal = Normal::new(2.0, 3.0).unwrap();
/// let v = normal.sample(&mut rand::thread_rng());
/// let v = normal.sample(&mut rand::rng());
/// println!("{} is from a N(2, 9) distribution", v)
/// ```
///
@ -215,7 +215,7 @@ where
/// ```
/// # use rand::prelude::*;
/// # use rand_distr::{Normal, StandardNormal};
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// let z = StandardNormal.sample(&mut rng);
/// let x1 = Normal::new(0.0, 1.0).unwrap().from_zscore(z);
/// let x2 = Normal::new(2.0, -3.0).unwrap().from_zscore(z);
@ -266,7 +266,7 @@ where
///
/// // mean 2, standard deviation 3
/// let log_normal = LogNormal::new(2.0, 3.0).unwrap();
/// let v = log_normal.sample(&mut rand::thread_rng());
/// let v = log_normal.sample(&mut rand::rng());
/// println!("{} is from an ln N(2, 9) distribution", v)
/// ```
#[derive(Clone, Copy, Debug, PartialEq)]
@ -341,7 +341,7 @@ where
/// ```
/// # use rand::prelude::*;
/// # use rand_distr::{LogNormal, StandardNormal};
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// let z = StandardNormal.sample(&mut rng);
/// let x1 = LogNormal::from_mean_cv(3.0, 1.0).unwrap().from_zscore(z);
/// let x2 = LogNormal::from_mean_cv(2.0, 4.0).unwrap().from_zscore(z);

View File

@ -45,7 +45,7 @@ impl std::error::Error for Error {}
/// use rand_distr::{NormalInverseGaussian, Distribution};
///
/// let norm_inv_gauss = NormalInverseGaussian::new(2.0, 1.0).unwrap();
/// let v = norm_inv_gauss.sample(&mut rand::thread_rng());
/// let v = norm_inv_gauss.sample(&mut rand::rng());
/// println!("{} is from a normal-inverse Gaussian(2, 1) distribution", v);
/// ```
#[derive(Debug, Clone, Copy, PartialEq)]

View File

@ -32,7 +32,7 @@ use rand::Rng;
/// use rand::prelude::*;
/// use rand_distr::Pareto;
///
/// let val: f64 = thread_rng().sample(Pareto::new(1., 2.).unwrap());
/// let val: f64 = rand::rng().sample(Pareto::new(1., 2.).unwrap());
/// println!("{}", val);
/// ```
#[derive(Clone, Copy, Debug, PartialEq)]

View File

@ -32,7 +32,7 @@ use rand::Rng;
/// use rand_distr::{Pert, Distribution};
///
/// let d = Pert::new(0., 5.).with_mode(2.5).unwrap();
/// let v = d.sample(&mut rand::thread_rng());
/// let v = d.sample(&mut rand::rng());
/// println!("{} is from a PERT distribution", v);
/// ```
///

View File

@ -36,7 +36,7 @@ use rand::Rng;
/// use rand_distr::{Poisson, Distribution};
///
/// let poi = Poisson::new(2.0).unwrap();
/// let v: f64 = poi.sample(&mut rand::thread_rng());
/// let v: f64 = poi.sample(&mut rand::rng());
/// println!("{} is from a Poisson(2) distribution", v);
/// ```
#[derive(Clone, Copy, Debug, PartialEq)]

View File

@ -45,7 +45,7 @@ use rand::Rng;
///
/// // location 2, scale 3, shape 1
/// let skew_normal = SkewNormal::new(2.0, 3.0, 1.0).unwrap();
/// let v = skew_normal.sample(&mut rand::thread_rng());
/// let v = skew_normal.sample(&mut rand::rng());
/// println!("{} is from a SN(2, 3, 1) distribution", v)
/// ```
///

View File

@ -42,7 +42,7 @@ use serde::{Deserialize, Serialize};
/// use rand_distr::{StudentT, Distribution};
///
/// let t = StudentT::new(11.0).unwrap();
/// let v = t.sample(&mut rand::thread_rng());
/// let v = t.sample(&mut rand::rng());
/// println!("{} is from a t(11) distribution", v)
/// ```
#[derive(Clone, Copy, Debug, PartialEq)]

View File

@ -33,7 +33,7 @@ use rand::Rng;
/// use rand_distr::{Triangular, Distribution};
///
/// let d = Triangular::new(0., 5., 2.5).unwrap();
/// let v = d.sample(&mut rand::thread_rng());
/// let v = d.sample(&mut rand::rng());
/// println!("{} is from a triangular distribution", v);
/// ```
///

View File

@ -32,7 +32,7 @@ use rand::Rng;
/// ```
/// use rand_distr::{UnitBall, Distribution};
///
/// let v: [f64; 3] = UnitBall.sample(&mut rand::thread_rng());
/// let v: [f64; 3] = UnitBall.sample(&mut rand::rng());
/// println!("{:?} is from the unit ball.", v)
/// ```
#[derive(Clone, Copy, Debug)]

View File

@ -30,7 +30,7 @@ use rand::Rng;
/// ```
/// use rand_distr::{UnitCircle, Distribution};
///
/// let v: [f64; 2] = UnitCircle.sample(&mut rand::thread_rng());
/// let v: [f64; 2] = UnitCircle.sample(&mut rand::rng());
/// println!("{:?} is from the unit circle.", v)
/// ```
///

View File

@ -31,7 +31,7 @@ use rand::Rng;
/// ```
/// use rand_distr::{UnitDisc, Distribution};
///
/// let v: [f64; 2] = UnitDisc.sample(&mut rand::thread_rng());
/// let v: [f64; 2] = UnitDisc.sample(&mut rand::rng());
/// println!("{:?} is from the unit Disc.", v)
/// ```
#[derive(Clone, Copy, Debug)]

View File

@ -32,7 +32,7 @@ use rand::Rng;
/// ```
/// use rand_distr::{UnitSphere, Distribution};
///
/// let v: [f64; 3] = UnitSphere.sample(&mut rand::thread_rng());
/// let v: [f64; 3] = UnitSphere.sample(&mut rand::rng());
/// println!("{:?} is from the unit sphere surface.", v)
/// ```
///

View File

@ -30,7 +30,7 @@ use rand::Rng;
/// use rand::prelude::*;
/// use rand_distr::Weibull;
///
/// let val: f64 = thread_rng().sample(Weibull::new(1., 10.).unwrap());
/// let val: f64 = rand::rng().sample(Weibull::new(1., 10.).unwrap());
/// println!("{}", val);
/// ```
#[derive(Clone, Copy, Debug, PartialEq)]

View File

@ -47,7 +47,7 @@ use serde::{Deserialize, Serialize};
/// let choices = vec!['a', 'b', 'c'];
/// let weights = vec![2, 1, 1];
/// let dist = WeightedAliasIndex::new(weights).unwrap();
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// for _ in 0..100 {
/// // 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c'
/// println!("{}", choices[dist.sample(&mut rng)]);

View File

@ -66,7 +66,7 @@ use serde::{Deserialize, Serialize};
/// let mut dist = WeightedTreeIndex::new(&weights).unwrap();
/// dist.push(1).unwrap();
/// dist.update(1, 1).unwrap();
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// let mut samples = [0; 3];
/// for _ in 0..100 {
/// // 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c'

View File

@ -36,7 +36,7 @@ use rand::{distr::OpenClosed01, Rng};
/// use rand::prelude::*;
/// use rand_distr::Zeta;
///
/// let val: f64 = thread_rng().sample(Zeta::new(1.5).unwrap());
/// let val: f64 = rand::rng().sample(Zeta::new(1.5).unwrap());
/// println!("{}", val);
/// ```
///

View File

@ -35,7 +35,7 @@ use rand::Rng;
/// use rand::prelude::*;
/// use rand_distr::Zipf;
///
/// let val: f64 = thread_rng().sample(Zipf::new(10, 1.5).unwrap());
/// let val: f64 = rand::rng().sample(Zipf::new(10, 1.5).unwrap());
/// println!("{}", val);
/// ```
///

View File

@ -47,7 +47,7 @@
//! let rng = Pcg64Mcg::from_os_rng();
//! # let _: Pcg64Mcg = rng;
//! ```
//! 3. **From a master generator.** This could be [`rand::thread_rng`]
//! 3. **From a master generator.** This could be [`rand::rng`]
//! (effectively a fresh seed without the need for a syscall on each usage)
//! or a deterministic generator such as [`rand_chacha::ChaCha8Rng`].
//! Beware that should a weak master generator be used, correlations may be
@ -77,7 +77,7 @@
//! [Random Values]: https://rust-random.github.io/book/guide-values.html
//! [`RngCore`]: rand_core::RngCore
//! [`SeedableRng`]: rand_core::SeedableRng
//! [`rand::thread_rng`]: https://docs.rs/rand/latest/rand/fn.thread_rng.html
//! [`rand::rng`]: https://docs.rs/rand/latest/rand/fn.rng.html
//! [`rand::Rng`]: https://docs.rs/rand/latest/rand/trait.Rng.html
//! [`rand_chacha::ChaCha8Rng`]: https://docs.rs/rand_chacha/latest/rand_chacha/struct.ChaCha8Rng.html

View File

@ -34,7 +34,7 @@ use serde::{Deserialize, Serialize};
/// use rand::distr::{Bernoulli, Distribution};
///
/// let d = Bernoulli::new(0.3).unwrap();
/// let v = d.sample(&mut rand::thread_rng());
/// let v = d.sample(&mut rand::rng());
/// println!("{} is from a Bernoulli distribution", v);
/// ```
///

View File

@ -48,10 +48,9 @@ pub trait Distribution<T> {
/// # Example
///
/// ```
/// use rand::thread_rng;
/// use rand::distr::{Distribution, Alphanumeric, Uniform, Standard};
///
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
///
/// // Vec of 16 x f32:
/// let v: Vec<f32> = Standard.sample_iter(&mut rng).take(16).collect();
@ -88,10 +87,9 @@ pub trait Distribution<T> {
/// # Example
///
/// ```
/// use rand::thread_rng;
/// use rand::distr::{Distribution, Uniform};
///
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
///
/// let die = Uniform::new_inclusive(1, 6).unwrap();
/// let even_number = die.map(|num| num % 2 == 0);

View File

@ -32,10 +32,10 @@ use serde::{Deserialize, Serialize};
///
/// # Example
/// ```
/// use rand::{thread_rng, Rng};
/// use rand::Rng;
/// use rand::distr::OpenClosed01;
///
/// let val: f32 = thread_rng().sample(OpenClosed01);
/// let val: f32 = rand::rng().sample(OpenClosed01);
/// println!("f32 from (0, 1): {}", val);
/// ```
///
@ -59,10 +59,10 @@ pub struct OpenClosed01;
///
/// # Example
/// ```
/// use rand::{thread_rng, Rng};
/// use rand::Rng;
/// use rand::distr::Open01;
///
/// let val: f32 = thread_rng().sample(Open01);
/// let val: f32 = rand::rng().sample(Open01);
/// println!("f32 from (0, 1): {}", val);
/// ```
///

View File

@ -34,10 +34,10 @@ use serde::{Deserialize, Serialize};
/// # Example
///
/// ```
/// use rand::{Rng, thread_rng};
/// use rand::Rng;
/// use rand::distr::Alphanumeric;
///
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// let chars: String = (0..7).map(|_| rng.sample(Alphanumeric) as char).collect();
/// println!("Random chars: {}", chars);
/// ```
@ -46,7 +46,7 @@ use serde::{Deserialize, Serialize};
/// a random `String`, and offers more efficient allocation:
/// ```
/// use rand::distr::{Alphanumeric, DistString};
/// let string = Alphanumeric.sample_string(&mut rand::thread_rng(), 16);
/// let string = Alphanumeric.sample_string(&mut rand::rng(), 16);
/// println!("Random string: {}", string);
/// ```
///
@ -163,7 +163,7 @@ impl Distribution<bool> for Standard {
/// #![feature(portable_simd)]
/// use std::simd::prelude::*;
/// use rand::prelude::*;
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
///
/// let x = u16x8::splat(rng.random::<u8>() as u16);
/// let mask = u16x8::splat(1) << u16x8::from([0, 1, 2, 3, 4, 5, 6, 7]);

View File

@ -38,7 +38,7 @@ use alloc::string::String;
///
/// let vowels = ['a', 'e', 'i', 'o', 'u'];
/// let vowels_dist = Slice::new(&vowels).unwrap();
/// let rng = rand::thread_rng();
/// let rng = rand::rng();
///
/// // build a string of 10 vowels
/// let vowel_string: String = rng
@ -58,7 +58,7 @@ use alloc::string::String;
/// use rand::seq::IndexedRandom;
///
/// let vowels = ['a', 'e', 'i', 'o', 'u'];
/// let mut rng = rand::thread_rng();
/// let mut rng = rand::rng();
///
/// println!("{}", vowels.choose(&mut rng).unwrap())
/// ```

View File

@ -26,10 +26,10 @@
//! # Example usage
//!
//! ```
//! use rand::{Rng, thread_rng};
//! use rand::Rng;
//! use rand::distr::Uniform;
//!
//! let mut rng = thread_rng();
//! let mut rng = rand::rng();
//! let side = Uniform::new(-10.0, 10.0).unwrap();
//!
//! // sample between 1 and 10 points
@ -94,7 +94,7 @@
//!
//! let (low, high) = (MyF32(17.0f32), MyF32(22.0f32));
//! let uniform = Uniform::new(low, high).unwrap();
//! let x = uniform.sample(&mut thread_rng());
//! let x = uniform.sample(&mut rand::rng());
//! ```
//!
//! [`SampleUniform`]: crate::distr::uniform::SampleUniform
@ -178,7 +178,7 @@ use serde::{Deserialize, Serialize};
/// use rand::distr::{Distribution, Uniform};
///
/// let between = Uniform::try_from(10..10000).unwrap();
/// let mut rng = rand::thread_rng();
/// let mut rng = rand::rng();
/// let mut sum = 0;
/// for _ in 0..1000 {
/// sum += between.sample(&mut rng);
@ -191,7 +191,7 @@ use serde::{Deserialize, Serialize};
/// ```
/// use rand::Rng;
///
/// let mut rng = rand::thread_rng();
/// let mut rng = rand::rng();
/// println!("{}", rng.gen_range(0..10));
/// ```
///
@ -315,10 +315,10 @@ pub trait UniformSampler: Sized {
/// Note that to use this method in a generic context, the type needs to be
/// retrieved via `SampleUniform::Sampler` as follows:
/// ```
/// use rand::{thread_rng, distr::uniform::{SampleUniform, UniformSampler}};
/// use rand::distr::uniform::{SampleUniform, UniformSampler};
/// # #[allow(unused)]
/// fn sample_from_range<T: SampleUniform>(lb: T, ub: T) -> T {
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// <T as SampleUniform>::Sampler::sample_single(lb, ub, &mut rng).unwrap()
/// }
/// ```

View File

@ -64,7 +64,7 @@ use serde::{Deserialize, Serialize};
/// let choices = ['a', 'b', 'c'];
/// let weights = [2, 1, 1];
/// let dist = WeightedIndex::new(&weights).unwrap();
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// for _ in 0..100 {
/// // 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c'
/// println!("{}", choices[dist.sample(&mut rng)]);

View File

@ -20,7 +20,7 @@
//! use rand::prelude::*;
//!
//! // Get an RNG:
//! let mut rng = rand::thread_rng();
//! let mut rng = rand::rng();
//!
//! // Try printing a random unicode code point (probably a bad idea)!
//! println!("char: '{}'", rng.random::<char>());
@ -104,7 +104,18 @@ pub mod seq;
// Public exports
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
pub use crate::rngs::thread::thread_rng;
pub use crate::rngs::thread::rng;
/// Access the thread-local generator
///
/// Use [`rand::rng()`](rng()) instead.
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[deprecated(since = "0.9.0", note = "renamed to `rng`")]
#[inline]
pub fn thread_rng() -> crate::rngs::ThreadRng {
rng()
}
pub use rng::{Fill, Rng};
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
@ -112,7 +123,7 @@ use crate::distr::{Distribution, Standard};
/// Generates a random value using the thread-local random number generator.
///
/// This function is simply a shortcut for `thread_rng().gen()`:
/// This function is simply a shortcut for `rand::rng().gen()`:
///
/// - See [`ThreadRng`] for documentation of the generator and security
/// - See [`Standard`] for documentation of supported types and distributions
@ -143,9 +154,9 @@ use crate::distr::{Distribution, Standard};
/// *x = rand::random()
/// }
///
/// // can be made faster by caching thread_rng
/// // can be made faster by caching rand::rng
///
/// let mut rng = rand::thread_rng();
/// let mut rng = rand::rng();
///
/// for x in v.iter_mut() {
/// *x = rng.random();
@ -160,7 +171,7 @@ pub fn random<T>() -> T
where
Standard: Distribution<T>,
{
thread_rng().random()
rng().random()
}
#[cfg(test)]

View File

@ -14,7 +14,7 @@
//!
//! ```
//! use rand::prelude::*;
//! # let mut r = StdRng::from_rng(&mut thread_rng());
//! # let mut r = StdRng::from_rng(&mut rand::rng());
//! # let _: f32 = r.random();
//! ```
@ -32,7 +32,4 @@ pub use crate::rngs::ThreadRng;
#[doc(no_inline)]
pub use crate::seq::{IndexedMutRandom, IndexedRandom, IteratorRandom, SliceRandom};
#[doc(no_inline)]
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
pub use crate::{random, thread_rng};
#[doc(no_inline)]
pub use crate::{CryptoRng, Rng, RngCore, SeedableRng};

View File

@ -37,7 +37,7 @@ use zerocopy::IntoBytes;
///
/// 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`
/// (which is how `from_rng(thread_rng())` works); also it still works directly
/// (which is how `from_rng(rand::rng())` works); 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
@ -47,14 +47,13 @@ use zerocopy::IntoBytes;
/// Example:
///
/// ```
/// # use rand::thread_rng;
/// use rand::Rng;
///
/// fn foo<R: Rng + ?Sized>(rng: &mut R) -> f32 {
/// rng.random()
/// }
///
/// # let v = foo(&mut thread_rng());
/// # let v = foo(&mut rand::rng());
/// ```
pub trait Rng: RngCore {
/// Return a random value via the [`Standard`] distribution.
@ -62,9 +61,9 @@ pub trait Rng: RngCore {
/// # Example
///
/// ```
/// use rand::{thread_rng, Rng};
/// use rand::Rng;
///
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// let x: u32 = rng.random();
/// println!("{}", x);
/// println!("{:?}", rng.random::<(f64, bool)>());
@ -81,9 +80,9 @@ pub trait Rng: RngCore {
/// though note that generated values will differ.
///
/// ```
/// use rand::{thread_rng, Rng};
/// use rand::Rng;
///
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// let tuple: (u8, i32, char) = rng.random(); // arbitrary tuple support
///
/// let arr1: [f32; 32] = rng.random(); // array construction
@ -131,10 +130,10 @@ pub trait Rng: RngCore {
/// ### Example
///
/// ```
/// use rand::{thread_rng, Rng};
/// use rand::Rng;
/// use rand::distr::Uniform;
///
/// let mut rng = thread_rng();
/// 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.
@ -152,10 +151,10 @@ pub trait Rng: RngCore {
/// # Example
///
/// ```
/// use rand::{thread_rng, Rng};
/// use rand::Rng;
/// use rand::distr::{Alphanumeric, Uniform, Standard};
///
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
///
/// // Vec of 16 x f32:
/// let v: Vec<f32> = (&mut rng).sample_iter(Standard).take(16).collect();
@ -197,10 +196,10 @@ pub trait Rng: RngCore {
/// # Example
///
/// ```
/// use rand::{thread_rng, Rng};
/// use rand::Rng;
///
/// let mut arr = [0i8; 20];
/// thread_rng().fill(&mut arr[..]);
/// rand::rng().fill(&mut arr[..]);
/// ```
///
/// [`fill_bytes`]: RngCore::fill_bytes
@ -225,9 +224,9 @@ pub trait Rng: RngCore {
/// # Example
///
/// ```
/// use rand::{thread_rng, Rng};
/// use rand::Rng;
///
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
///
/// // Exclusive range
/// let n: u32 = rng.gen_range(..10);
@ -259,9 +258,9 @@ pub trait Rng: RngCore {
/// # Example
///
/// ```
/// use rand::{thread_rng, Rng};
/// use rand::Rng;
///
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// println!("{}", rng.gen_bool(1.0 / 3.0));
/// ```
///
@ -295,9 +294,9 @@ pub trait Rng: RngCore {
/// # Example
///
/// ```
/// use rand::{thread_rng, Rng};
/// use rand::Rng;
///
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// println!("{}", rng.gen_ratio(2, 3));
/// ```
///

View File

@ -17,7 +17,7 @@
//!
//! - [`OsRng`] is a stateless interface over the operating system's random number
//! source. This is typically secure with some form of periodic re-seeding.
//! - [`ThreadRng`], provided by the [`thread_rng`] function, is a handle to a
//! - [`ThreadRng`], provided by [`crate::rng()`], is a handle to a
//! thread-local generator with periodic seeding from [`OsRng`]. Because this
//! is local, it is typically much faster than [`OsRng`]. It should be
//! secure, but see documentation on [`ThreadRng`].
@ -67,7 +67,6 @@
//! [`RngCore`]: crate::RngCore
//! [`CryptoRng`]: crate::CryptoRng
//! [`SeedableRng`]: crate::SeedableRng
//! [`thread_rng`]: crate::thread_rng
//! [`rdrand`]: https://crates.io/crates/rdrand
//! [`rand_jitter`]: https://crates.io/crates/rand_jitter
//! [`rand_chacha`]: https://crates.io/crates/rand_chacha

View File

@ -114,17 +114,17 @@ impl RngCore for SmallRng {
}
impl SmallRng {
/// Construct an instance seeded from the thread-local RNG
/// Construct an instance seeded from `rand::rng`
///
/// # Panics
///
/// This method panics only if [`thread_rng`](crate::thread_rng) fails to
/// This method panics only if [`crate::rng()`] fails to
/// initialize.
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
#[inline(always)]
pub fn from_thread_rng() -> Self {
let mut seed = <Rng as SeedableRng>::Seed::default();
crate::thread_rng().fill_bytes(seed.as_mut());
crate::rng().fill_bytes(seed.as_mut());
SmallRng(Rng::from_seed(seed))
}
}

View File

@ -41,7 +41,8 @@ const THREAD_RNG_RESEED_THRESHOLD: u64 = 1024 * 64;
/// A reference to the thread-local generator
///
/// This type is a reference to a lazily-initialized thread-local generator.
/// An instance can be obtained via [`thread_rng`] or via `ThreadRng::default()`.
/// An instance can be obtained via [`rand::rng()`][crate::rng())] or via
/// `ThreadRng::default()`.
/// The handle cannot be passed between threads (is not `Send` or `Sync`).
///
/// `ThreadRng` uses the same CSPRNG as [`StdRng`], ChaCha12. As with
@ -58,7 +59,7 @@ const THREAD_RNG_RESEED_THRESHOLD: u64 = 1024 * 64;
/// let pid = unsafe { libc::fork() };
/// if pid == 0 {
/// // Reseed ThreadRng in child processes:
/// rand::thread_rng().reseed();
/// rand::rng().reseed();
/// }
/// }
/// ```
@ -102,11 +103,11 @@ impl fmt::Debug for ThreadRng {
}
thread_local!(
// We require Rc<..> to avoid premature freeing when thread_rng is used
// We require Rc<..> to avoid premature freeing when ThreadRng is used
// within thread-local destructors. See #968.
static THREAD_RNG_KEY: Rc<UnsafeCell<ReseedingRng<Core, OsRng>>> = {
let r = Core::try_from_os_rng().unwrap_or_else(|err|
panic!("could not initialize thread_rng: {}", err));
panic!("could not initialize ThreadRng: {}", err));
let rng = ReseedingRng::new(r,
THREAD_RNG_RESEED_THRESHOLD,
OsRng);
@ -114,31 +115,38 @@ thread_local!(
}
);
/// Access the thread-local generator
/// Access a local, pre-initialized generator
///
/// Returns a reference to the local [`ThreadRng`], initializing the generator
/// on the first call on each thread.
/// This is a reasonably fast unpredictable thread-local instance of [`ThreadRng`].
///
/// See also [`crate::rngs`] for alternatives.
///
/// # Example
///
/// Example usage:
/// ```
/// use rand::Rng;
/// use rand::prelude::*;
///
/// # fn main() {
/// // rand::random() may be used instead of rand::thread_rng().gen():
/// println!("A random boolean: {}", rand::random::<bool>());
///
/// let mut rng = rand::thread_rng();
/// let mut numbers = [1, 2, 3, 4, 5];
/// numbers.shuffle(&mut rand::rng());
/// println!("Numbers: {numbers:?}");
///
/// // Using a local binding avoids an initialization-check on each usage:
/// let mut rng = rand::rng();
///
/// println!("True or false: {}", rng.random::<bool>());
/// println!("A simulated die roll: {}", rng.gen_range(1..=6));
/// # }
/// ```
pub fn thread_rng() -> ThreadRng {
pub fn rng() -> ThreadRng {
let rng = THREAD_RNG_KEY.with(|t| t.clone());
ThreadRng { rng }
}
impl Default for ThreadRng {
fn default() -> ThreadRng {
thread_rng()
rng()
}
}
@ -175,7 +183,7 @@ mod test {
#[test]
fn test_thread_rng() {
use crate::Rng;
let mut r = crate::thread_rng();
let mut r = crate::rng();
r.random::<i32>();
assert_eq!(r.gen_range(0..1), 0);
}
@ -184,9 +192,6 @@ mod test {
fn test_debug_output() {
// We don't care about the exact output here, but it must not include
// private CSPRNG state or the cache stored by BlockRng!
assert_eq!(
std::format!("{:?}", crate::thread_rng()),
"ThreadRng { .. }"
);
assert_eq!(std::format!("{:?}", crate::rng()), "ThreadRng { .. }");
}
}

View File

@ -24,10 +24,8 @@ use alloc::vec::Vec;
/// ```
/// use rand::seq::IteratorRandom;
///
/// let mut rng = rand::thread_rng();
///
/// let faces = "😀😎😐😕😠😢";
/// println!("I am {}!", faces.chars().choose(&mut rng).unwrap());
/// println!("I am {}!", faces.chars().choose(&mut rand::rng()).unwrap());
/// ```
/// Example output (non-deterministic):
/// ```none

View File

@ -42,11 +42,10 @@ pub trait IndexedRandom: Index<usize> {
/// # Example
///
/// ```
/// use rand::thread_rng;
/// use rand::seq::IndexedRandom;
///
/// let choices = [1, 2, 4, 8, 16, 32];
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// println!("{:?}", choices.choose(&mut rng));
/// assert_eq!(choices[..0].choose(&mut rng), None);
/// ```
@ -75,7 +74,7 @@ pub trait IndexedRandom: Index<usize> {
/// ```
/// use rand::seq::IndexedRandom;
///
/// let mut rng = &mut rand::thread_rng();
/// let mut rng = &mut rand::rng();
/// let sample = "Hello, audience!".as_bytes();
///
/// // collect the results into a vector:
@ -112,7 +111,7 @@ pub trait IndexedRandom: Index<usize> {
/// ```
/// use rand::seq::IndexedRandom;
///
/// let mut rng = &mut rand::thread_rng();
/// let mut rng = &mut rand::rng();
/// let sample = "Hello, audience!".as_bytes();
///
/// let a: [u8; 3] = sample.choose_multiple_array(&mut rng).unwrap();
@ -147,7 +146,7 @@ pub trait IndexedRandom: Index<usize> {
/// use rand::prelude::*;
///
/// let choices = [('a', 2), ('b', 1), ('c', 1), ('d', 0)];
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// // 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c',
/// // and 'd' will never be printed
/// println!("{:?}", choices.choose_weighted(&mut rng, |item| item.1).unwrap().0);
@ -201,7 +200,7 @@ pub trait IndexedRandom: Index<usize> {
/// use rand::prelude::*;
///
/// let choices = [('a', 2), ('b', 1), ('c', 1)];
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// // First Draw * Second Draw = total odds
/// // -----------------------
/// // (50% * 50%) + (25% * 67%) = 41.7% chance that the output is `['a', 'b']` in some order.
@ -308,7 +307,7 @@ pub trait IndexedMutRandom: IndexedRandom + IndexMut<usize> {
/// ```
/// use rand::seq::SliceRandom;
///
/// let mut rng = rand::thread_rng();
/// let mut rng = rand::rng();
/// let mut bytes = "Hello, random!".to_string().into_bytes();
/// bytes.shuffle(&mut rng);
/// let str = String::from_utf8(bytes).unwrap();
@ -328,9 +327,8 @@ pub trait SliceRandom: IndexedMutRandom {
///
/// ```
/// use rand::seq::SliceRandom;
/// use rand::thread_rng;
///
/// let mut rng = thread_rng();
/// let mut rng = rand::rng();
/// let mut y = [1, 2, 3, 4, 5];
/// println!("Unshuffled: {:?}", y);
/// y.shuffle(&mut rng);