diff --git a/src/lib.rs b/src/lib.rs
index 833fe0c0e46..f9092925471 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -121,9 +121,9 @@ pub use rng::{Fill, Rng};
#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
use crate::distr::{Distribution, Standard};
-/// Generates a random value using the thread-local random number generator.
+/// Generate a random value using the thread-local random number generator.
///
-/// This function is simply a shortcut for `rand::rng().gen()`:
+/// This function is shorthand for [rng()].[random()](Rng::random)
:
///
/// - See [`ThreadRng`] for documentation of the generator and security
/// - See [`Standard`] for documentation of supported types and distributions
@@ -142,21 +142,15 @@ use crate::distr::{Distribution, Standard};
/// }
/// ```
///
-/// If you're calling `random()` in a loop, caching the generator as in the
-/// following example can increase performance.
+/// If you're calling `random()` repeatedly, consider using a local `rng`
+/// handle to save an initialization-check on each usage:
///
/// ```
-/// use rand::Rng;
+/// use rand::Rng; // provides the `random` method
///
-/// let mut v = vec![1, 2, 3];
-///
-/// for x in v.iter_mut() {
-/// *x = rand::random()
-/// }
-///
-/// // can be made faster by caching rand::rng
+/// let mut rng = rand::rng(); // a local handle to the generator
///
-/// let mut rng = rand::rng();
+/// let mut v = vec![1, 2, 3];
///
/// for x in v.iter_mut() {
/// *x = rng.random();
@@ -174,6 +168,127 @@ where
rng().random()
}
+/// Return an iterator over [`random()`] variates
+///
+/// This function is shorthand for
+/// [rng()].[random_iter](Rng::random_iter)()
.
+///
+/// # Example
+///
+/// ```
+/// let v: Vec = rand::random_iter().take(5).collect();
+/// println!("{v:?}");
+/// ```
+#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
+#[inline]
+pub fn random_iter() -> distr::DistIter
+where
+ Standard: Distribution,
+{
+ rng().random_iter()
+}
+
+/// Generate a random value in the given range using the thread-local random number generator.
+///
+/// This function is shorthand for
+/// [rng()].[random_range](Rng::random_range)(range)
.
+///
+/// # Example
+///
+/// ```
+/// let y: f32 = rand::random_range(0.0..=1e9);
+/// println!("{}", y);
+///
+/// let words: Vec<&str> = "Mary had a little lamb".split(' ').collect();
+/// println!("{}", words[rand::random_range(..words.len())]);
+/// ```
+/// Note that the first example can also be achieved (without `collect`'ing
+/// to a `Vec`) using [`seq::IteratorRandom::choose`].
+#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
+#[inline]
+pub fn random_range(range: R) -> T
+where
+ T: distr::uniform::SampleUniform,
+ R: distr::uniform::SampleRange,
+{
+ rng().random_range(range)
+}
+
+/// Return a bool with a probability `p` of being true.
+///
+/// This function is shorthand for
+/// [rng()].[random_bool](Rng::random_bool)(p)
.
+///
+/// # Example
+///
+/// ```
+/// println!("{}", rand::random_bool(1.0 / 3.0));
+/// ```
+///
+/// # Panics
+///
+/// If `p < 0` or `p > 1`.
+#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
+#[inline]
+#[track_caller]
+pub fn random_bool(p: f64) -> bool {
+ rng().random_bool(p)
+}
+
+/// 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.
+///
+/// This function is shorthand for
+/// [rng()].[random_ratio](Rng::random_ratio)(numerator, denominator)
.
+///
+/// # Panics
+///
+/// If `denominator == 0` or `numerator > denominator`.
+///
+/// # Example
+///
+/// ```
+/// println!("{}", rand::random_ratio(2, 3));
+/// ```
+///
+/// [`Bernoulli`]: distr::Bernoulli
+#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
+#[inline]
+#[track_caller]
+pub fn random_ratio(numerator: u32, denominator: u32) -> bool {
+ rng().random_ratio(numerator, denominator)
+}
+
+/// Fill any type implementing [`Fill`] with random data
+///
+/// This function is shorthand for
+/// [rng()].[fill](Rng::fill)(dest)
.
+///
+/// # Example
+///
+/// ```
+/// let mut arr = [0i8; 20];
+/// rand::fill(&mut arr[..]);
+/// ```
+///
+/// Note that you can instead use [`random()`] to generate an array of random
+/// data, though this is slower for small elements (smaller than the RNG word
+/// size).
+#[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
+#[inline]
+#[track_caller]
+pub fn fill(dest: &mut T) {
+ dest.fill(&mut rng())
+}
+
#[cfg(test)]
mod test {
use super::*;
@@ -200,4 +315,11 @@ mod test {
(f32, (f64, (f64,))),
) = random();
}
+
+ #[test]
+ #[cfg(all(feature = "std", feature = "std_rng", feature = "getrandom"))]
+ fn test_range() {
+ let _n: usize = random_range(42..=43);
+ let _f: f32 = random_range(42.0..43.0);
+ }
}
diff --git a/src/rng.rs b/src/rng.rs
index a3657ed45f0..9ac481ed9ce 100644
--- a/src/rng.rs
+++ b/src/rng.rs
@@ -196,7 +196,9 @@ pub trait Rng: RngCore {
}
/// Return a bool with a probability of `numerator/denominator` of being
- /// true. I.e. `random_ratio(2, 3)` has chance of 2 in 3, or about 67%, of
+ /// 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`.
diff --git a/src/seq/iterator.rs b/src/seq/iterator.rs
index ad96b3baf79..b10d205676a 100644
--- a/src/seq/iterator.rs
+++ b/src/seq/iterator.rs
@@ -54,6 +54,15 @@ pub trait IteratorRandom: Iterator + Sized {
/// Consider instead using [`IteratorRandom::choose_stable`] to avoid
/// [`Iterator`] combinators which only change size hints from affecting the
/// results.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use rand::seq::IteratorRandom;
+ ///
+ /// let words = "Mary had a little lamb".split(' ');
+ /// println!("{}", words.choose(&mut rand::rng()).unwrap());
+ /// ```
fn choose(mut self, rng: &mut R) -> Option
where
R: Rng + ?Sized,