about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2014-03-16 18:43:47 -0700
committerBrian Anderson <banderson@mozilla.com>2014-03-18 18:22:33 -0700
commit8fcb8dd06506d2a371ef12eec6db855d18f32e17 (patch)
tree977d40f5a0889e0ef7341bbc99d13d3820817fba /src
parent891eab94a31739d6b0c330ebb7d4415529cfe1ee (diff)
downloadrust-8fcb8dd06506d2a371ef12eec6db855d18f32e17.tar.gz
rust-8fcb8dd06506d2a371ef12eec6db855d18f32e17.zip
std: Improve option docs
Diffstat (limited to 'src')
-rw-r--r--src/libstd/option.rs190
1 files changed, 170 insertions, 20 deletions
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index e4d843d8882..b498572f26e 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -8,21 +8,86 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Optionally nullable values (`Option` type)
+//! Optional values
 //!
-//! Type `Option` represents an optional value.
+//! Type `Option` represents an optional value: every `Option`
+//! is either `Some` and contains a value, or `None`, and
+//! does not. `Option` types are very common in Rust code, as
+//! they have a number of uses:
 //!
-//! Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
-//! languages you might use a nullable type, in Rust you would use an option
-//! type.
+//! * Initial values
+//! * Return values for functions that are not defined
+//!   over their entire input range (partial functions)
+//! * Return value for otherwise reporting simple errors, where `None` is
+//!   returned on error
+//! * Optional struct fields
+//! * Struct fields that can be loaned or "taken"
+//! * Optional function arguments
+//! * Nullable pointers
+//! * Swapping things out of difficult situations
 //!
-//! Options are most commonly used with pattern matching to query the presence
+//! Options are commonly paired with pattern matching to query the presence
 //! of a value and take action, always accounting for the `None` case.
 //!
-//! # Example
+//! ```
+//! # // FIXME This is not the greatest first example
+//! // cow_says contains the word "moo"
+//! let cow_says = Some("moo");
+//! // dog_says does not contain a value
+//! let dog_says: Option<&str> = None;
+//!
+//! // Pattern match to retrieve the value
+//! match (cow_says, dog_says) {
+//!     (Some(cow_words), Some(dog_words)) => {
+//!         println!("Cow says {} and dog says {}!", cow_words, dog_words);
+//!     }
+//!     (Some(cow_words), None) => println!("Cow says {}", cow_words),
+//!     (None, Some(dog_words)) => println!("Dog says {}", dog_words),
+//!     (None, None) => println!("Cow and dog are suspiciously silent")
+//! }
+//! ```
+//!
+//
+// FIXME: Show how `Option` is used in practice, with lots of methods
+//
+//! # Options and pointers ("nullable" pointers)
+//!
+//! Rust's pointer types must always point to a valid location; there are
+//! no "null" pointers. Instead, Rust has *optional* pointers, like
+//! the optional owned box, `Option<~T>`.
+//!
+//! The following example uses `Option` to create an optional box of
+//! `int`. Notice that in order to use the inner `int` value first the
+//! `check_optional` function needs to use pattern matching to
+//! determine whether the box has a value (i.e. it is `Some(...)`) or
+//! not (`None`).
 //!
 //! ```
-//! let msg = Some(~"howdy");
+//! let optional: Option<~int> = None;
+//! check_optional(&optional);
+//!
+//! let optional: Option<~int> = Some(~9000);
+//! check_optional(&optional);
+//!
+//! fn check_optional(optional: &Option<~int>) {
+//!     match *optional {
+//!         Some(ref p) => println!("have value {}", p),
+//!         None => println!("have no value")
+//!     }
+//! }
+//! ```
+//!
+//! This usage of `Option` to create safe nullable pointers is so
+//! common that Rust does special optimizations to make the
+//! representation of `Option<~T>` a single pointer. Optional pointers
+//! in Rust are stored as efficiently as any other pointer type.
+//!
+//! # Examples
+//!
+//! Basic pattern matching on `Option`:
+//!
+//! ```
+//! let msg = Some("howdy");
 //!
 //! // Take a reference to the contained string
 //! match msg {
@@ -33,9 +98,45 @@
 //! // Remove the contained string, destroying the Option
 //! let unwrapped_msg = match msg {
 //!     Some(m) => m,
-//!     None => ~"default message"
+//!     None => "default message"
 //! };
 //! ```
+//!
+//! Initialize a result to `None` before a loop:
+//!
+//! ```
+//! enum Kingdom { Plant(uint, &'static str), Animal(uint, &'static str) }
+//!
+//! // A list of data to search through.
+//! let all_the_big_things = [
+//!     Plant(250, "redwood"),
+//!     Plant(230, "noble fir"),
+//!     Plant(229, "sugar pine"),
+//!     Animal(25, "blue whale"),
+//!     Animal(19, "fin whale"),
+//!     Animal(15, "north pacific right whale"),
+//! ];
+//!
+//! // We're going to search for the name of the biggest animal,
+//! // but to start with we've just got `None`.
+//! let mut name_of_biggest_animal = None;
+//! let mut size_of_biggest_animal = 0;
+//! for big_thing in all_the_big_things.iter() {
+//!     match *big_thing {
+//!         Animal(size, name) if size > size_of_biggest_animal => {
+//!             // Now we've found the name of some big animal
+//!             size_of_biggest_animal = size;
+//!             name_of_biggest_animal = Some(name);
+//!         }
+//!         Animal(..) | Plant(..) => ()
+//!     }
+//! }
+//!
+//! match name_of_biggest_animal {
+//!     Some(name) => println!("the biggest animal is {}", name),
+//!     None => println!("there are no animals :(")
+//! }
+//! ```
 
 use any::Any;
 use clone::Clone;
@@ -46,7 +147,7 @@ use kinds::Send;
 use mem;
 use vec;
 
-/// The option type
+/// The `Option`
 #[deriving(Clone, Eq, Ord, TotalEq, TotalOrd, Show)]
 pub enum Option<T> {
     /// No value
@@ -64,7 +165,7 @@ impl<T> Option<T> {
     // Querying the contained values
     /////////////////////////////////////////////////////////////////////////
 
-    /// Returns true if the option contains a `Some` value
+    /// Returns `true` if the option is a `Some` value
     #[inline]
     pub fn is_some(&self) -> bool {
         match *self {
@@ -73,7 +174,7 @@ impl<T> Option<T> {
         }
     }
 
-    /// Returns true if the option equals `None`
+    /// Returns `true` if the option is a `None` value
     #[inline]
     pub fn is_none(&self) -> bool {
         !self.is_some()
@@ -84,6 +185,21 @@ impl<T> Option<T> {
     /////////////////////////////////////////////////////////////////////////
 
     /// Convert from `Option<T>` to `Option<&T>`
+    ///
+    /// # Example
+    ///
+    /// Convert an `Option<~str>` into an `Option<int>`, preserving the original.
+    /// The `map` method takes the `self` argument by value, consuming the original,
+    /// so this technique uses `as_ref` to first take an `Option` to a reference
+    /// to the value inside the original.
+    ///
+    /// ```
+    /// let num_as_str: Option<~str> = Some(~"10");
+    /// // First, cast `Option<~str>` to `Option<&~str>` with `as_ref`,
+    /// // then consume *that* with `map`, leaving `num_as_str` on the stack.
+    /// let num_as_int: Option<uint> = num_as_str.as_ref().map(|n| n.len());
+    /// println!("still can print num_as_str: {}", num_as_str);
+    /// ```
     #[inline]
     pub fn as_ref<'r>(&'r self) -> Option<&'r T> {
         match *self { Some(ref x) => Some(x), None => None }
@@ -118,6 +234,9 @@ impl<T> Option<T> {
     /////////////////////////////////////////////////////////////////////////
 
     /// Unwraps an option, yielding the content of a `Some`
+    ///
+    /// # Failure
+    ///
     /// Fails if the value is a `None` with a custom failure message provided by `msg`.
     #[inline]
     pub fn expect<M: Any + Send>(self, msg: M) -> T {
@@ -127,14 +246,11 @@ impl<T> Option<T> {
         }
     }
 
-    /// Moves a value out of an option type and returns it.
-    ///
-    /// Useful primarily for getting strings, vectors and unique pointers out
-    /// of option types without copying them.
+    /// Moves a value out of an option type and returns it, consuming the `Option`.
     ///
     /// # Failure
     ///
-    /// Fails if the value equals `None`.
+    /// Fails if the self value equals `None`.
     ///
     /// # Safety note
     ///
@@ -171,7 +287,17 @@ impl<T> Option<T> {
     // Transforming contained values
     /////////////////////////////////////////////////////////////////////////
 
-    /// Maps an `Option<T>` to `Option<U>` by applying a function to a contained value.
+    /// Maps an `Option<T>` to `Option<U>` by applying a function to a contained value
+    ///
+    /// # Example
+    ///
+    /// Convert an `Option<~str>` into an `Option<uint>`, consuming the original:
+    ///
+    /// ```
+    /// let num_as_str: Option<~str> = Some(~"10");
+    /// // `Option::map` takes self *by value*, consuming `num_as_str`
+    /// let num_as_int: Option<uint> = num_as_str.map(|n| n.len());
+    /// ```
     #[inline]
     pub fn map<U>(self, f: |T| -> U) -> Option<U> {
         match self { Some(x) => Some(f(x)), None => None }
@@ -359,7 +485,28 @@ impl<T> Option<T> {
 }
 
 impl<T: Default> Option<T> {
-    /// Returns the contained value or default (for this type)
+    /// Returns the contained value or a default
+    ///
+    /// Consumes the `self` argument then, if `Some`, returns the contained
+    /// value, otherwise if `None`, returns the default value for that
+    /// type.
+    ///
+    /// # Example
+    ///
+    /// Convert a string to an integer, turning poorly-formed strings
+    /// into 0 (the default value for integers). `from_str` converts
+    /// a string to any other type that implements `FromStr`, returning
+    /// `None` on error.
+    ///
+    /// ```
+    /// let good_year_from_input = "1909";
+    /// let bad_year_from_input = "190blarg";
+    /// let good_year = from_str(good_year_from_input).unwrap_or_default();
+    /// let bad_year = from_str(bad_year_from_input).unwrap_or_default();
+    ///
+    /// assert_eq!(1909, good_year);
+    /// assert_eq!(0, bad_year);
+    /// ```
     #[inline]
     pub fn unwrap_or_default(self) -> T {
         match self {
@@ -382,7 +529,10 @@ impl<T> Default for Option<T> {
 // The Option Iterator
 /////////////////////////////////////////////////////////////////////////////
 
-/// An iterator that yields either one or zero elements
+/// An `Option` iterator that yields either one or zero elements
+///
+/// The `Item` iterator is returned by the `iter`, `mut_iter` and `move_iter`
+/// methods on `Option`.
 #[deriving(Clone)]
 pub struct Item<A> {
     priv opt: Option<A>