[−][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 likerandom()
). For integers this is normally the full representable range (e.g. from0u32
tostd::u32::MAX
), for floats this is between 0 and 1, and some other types are supported, including arrays and tuples. See theStandard
distribution which provides the implementations.gen_range
samples from a specific range of values; this is likegen
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:
Rng::sample_iter
allows iterating over values from a chosen distribution.Rng::gen_bool
generates boolean "events" with a given probability.Rng::fill
andRng::try_fill
are fast alternatives to fill a slice of integers.Rng::shuffle
randomly shuffles elements in a slice.Rng::choose
picks one element at random from a slice.
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 |
FromEntropy |
A convenience extension to |
Rand |
[ Deprecated ] A type that can be randomly generated using an |
Rng |
An automatically-implemented extension trait on |
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 |
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. |
weak_rng |
[ Deprecated ] DEPRECATED: use |