[][src]Crate rand

Utilities for random number generation

Rand provides utilities to generate random numbers, to convert them to useful types and distributions, and some randomness-related algorithms.

Basic usage

To get you started quickly, the easiest and highest-level way to get a random value is to use random().

let x: u8 = rand::random();
println!("{}", x);

let y = rand::random::<f64>();
println!("{}", y);

if rand::random() { // generates a boolean
    println!("Heads!");
}

This supports generating most common types but is not very flexible, thus you probably want to learn a bit more about the Rand library.

The two-step process to get a random value

Generating random values is typically a two-step process:

  • get some random data (an integer or bit/byte sequence) from a random number generator (RNG);
  • use some function to transform that data into the type of value you want (this function is an implementation of some distribution describing the kind of value produced).

Rand represents the first step with the RngCore trait and the second step via a combination of the Rng extension trait and the distributions module. In practice you probably won't use RngCore directly unless you are implementing a random number generator (RNG).

There are many kinds of RNGs, with different trade-offs. You can read more about them in the rngs module and even more in the prng module, however, often you can just use thread_rng(). This function automatically initializes an RNG in thread-local memory, then returns a reference to it. It is fast, good quality, and secure (unpredictable).

To turn the output of the RNG into something usable, you usually want to use the methods from the Rng trait. Some of the most useful methods are:

  • gen generates a random value appropriate for the type (just like random()). For integers this is normally the full representable range (e.g. from 0u32 to std::u32::MAX), for floats this is between 0 and 1, and some other types are supported, including arrays and tuples. See the Standard distribution which provides the implementations.
  • gen_range samples from a specific range of values; this is like gen but with specific upper and lower bounds.
  • sample samples directly from some distribution.

random() is defined using just the above: thread_rng().gen().

Distributions

What are distributions, you ask? Specifying only the type and range of values (known as the sample space) is not enough; samples must also have a probability distribution, describing the relative probability of sampling each value in that space.

In many cases a uniform distribution is used, meaning roughly that each value is equally likely (or for "continuous" types like floats, that each equal-sized sub-range has the same probability of containing a sample). gen and gen_range both use statistically uniform distributions.

The distributions module provides implementations of some other distributions, including Normal, Log-Normal and Exponential.

It is worth noting that the functionality already mentioned is implemented with distributions: gen samples values using the Standard distribution, while gen_range uses Uniform.

Importing (prelude)

The most convenient way to import items from Rand is to use the prelude. This includes the most important parts of Rand, but only those unlikely to cause name conflicts.

Note that Rand 0.5 has significantly changed the module organization and contents relative to previous versions. Where possible old names have been kept (but are hidden in the documentation), however these will be removed in the future. We therefore recommend migrating to use the prelude or the new module organization in your imports.

Examples

use rand::prelude::*;

// thread_rng is often the most convenient source of randomness:
let mut rng = thread_rng();
 
if rng.gen() { // random bool
    let x: f64 = rng.gen(); // random number in range [0, 1)
    println!("x is: {}", x);
    let ch = rng.gen::<char>(); // using type annotation
    println!("char is: {}", ch);
    println!("Number from 0 to 9: {}", rng.gen_range(0, 10));
}

More functionality

The Rng trait includes a few more methods not mentioned above:

For more slice/sequence related functionality, look in the seq module.

There is also distributions::WeightedChoice, which can be used to pick elements at random with some probability. But it does not work well at the moment and is going through a redesign.

Error handling

Error handling in Rand is a compromise between simplicity and necessity. Most RNGs and sampling functions will never produce errors, and making these able to handle errors would add significant overhead (to code complexity and ergonomics of usage at least, and potentially also performance, depending on the approach). However, external RNGs can fail, and being able to handle this is important.

It has therefore been decided that most methods should not return a Result type, with as exceptions Rng::try_fill, RngCore::try_fill_bytes, and SeedableRng::from_rng.

Note that it is the RNG that panics when it fails but is not used through a method that can report errors. Currently Rand contains only three RNGs that can return an error (and thus may panic), and documents this property: OsRng, EntropyRng and ReadRng. Other RNGs, like ThreadRng and StdRng, can be used with all methods without concern.

One further problem is that if Rand is unable to get any external randomness when initializing an RNG with EntropyRng, it will panic in FromEntropy::from_entropy, and notably in thread_rng(). Except by compromising security, this problem is as unsolvable as running out of memory.

Distinction between Rand and rand_core

The rand_core crate provides the necessary traits and functionality for implementing RNGs; this includes the RngCore and SeedableRng traits and the Error type. Crates implementing RNGs should depend on rand_core.

Applications and libraries consuming random values are encouraged to use the Rand crate, which re-exports the common parts of rand_core.

More examples

For some inspiration, see the examples:

Modules

distributions

Generating random samples from probability distributions.

prelude

Convenience re-export of common members

prng

Pseudo-random number generators.

rngs

Random number generators and adapters for common usage:

seq

Functions for randomly accessing and sampling sequences.

Structs

AsciiGenerator[
Deprecated
]

Iterator which will continuously generate random ascii characters.

Error

Error type of random number generators

Generator[
Deprecated
]

Iterator which will generate a stream of random items.

Enums

ErrorKind

Error kind which can be matched over.

Traits

AsByteSliceMut

Trait for casting types to byte slices

CryptoRng

A marker trait used to indicate that an RngCore or BlockRngCore implementation is supposed to be cryptographically secure.

FromEntropy

A convenience extension to SeedableRng allowing construction from fresh entropy. This trait is automatically implemented for any PRNG implementing SeedableRng and is not intended to be implemented by users.

Rand[
Deprecated
]

A type that can be randomly generated using an Rng.

Rng

An automatically-implemented extension trait on RngCore providing high-level generic methods for sampling values and other convenience methods.

RngCore

The core of a random number generator.

SeedableRng

A random number generator that can be explicitly seeded.

Functions

random

Generates a random value using the thread-local random number generator.

sample[
Deprecated
]

DEPRECATED: use seq::sample_iter instead.

thread_rng

Retrieve the lazily-initialized thread-local random number generator, seeded by the system. Intended to be used in method chaining style, e.g. thread_rng().gen::<i32>(), or cached locally, e.g. let mut rng = thread_rng();.

weak_rng[
Deprecated
]

DEPRECATED: use SmallRng instead.