(index<- )        ./libstd/option.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   1  // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  //! Optional values
  12  //!
  13  //! Type `Option` represents an optional value: every `Option`
  14  //! is either `Some` and contains a value, or `None`, and
  15  //! does not. `Option` types are very common in Rust code, as
  16  //! they have a number of uses:
  17  //!
  18  //! * Initial values
  19  //! * Return values for functions that are not defined
  20  //!   over their entire input range (partial functions)
  21  //! * Return value for otherwise reporting simple errors, where `None` is
  22  //!   returned on error
  23  //! * Optional struct fields
  24  //! * Struct fields that can be loaned or "taken"
  25  //! * Optional function arguments
  26  //! * Nullable pointers
  27  //! * Swapping things out of difficult situations
  28  //!
  29  //! Options are commonly paired with pattern matching to query the presence
  30  //! of a value and take action, always accounting for the `None` case.
  31  //!
  32  //! ```
  33  //! # // FIXME This is not the greatest first example
  34  //! // cow_says contains the word "moo"
  35  //! let cow_says = Some("moo");
  36  //! // dog_says does not contain a value
  37  //! let dog_says: Option<&str> = None;
  38  //!
  39  //! // Pattern match to retrieve the value
  40  //! match (cow_says, dog_says) {
  41  //!     (Some(cow_words), Some(dog_words)) => {
  42  //!         println!("Cow says {} and dog says {}!", cow_words, dog_words);
  43  //!     }
  44  //!     (Some(cow_words), None) => println!("Cow says {}", cow_words),
  45  //!     (None, Some(dog_words)) => println!("Dog says {}", dog_words),
  46  //!     (None, None) => println!("Cow and dog are suspiciously silent")
  47  //! }
  48  //! ```
  49  //!
  50  //
  51  // FIXME: Show how `Option` is used in practice, with lots of methods
  52  //
  53  //! # Options and pointers ("nullable" pointers)
  54  //!
  55  //! Rust's pointer types must always point to a valid location; there are
  56  //! no "null" pointers. Instead, Rust has *optional* pointers, like
  57  //! the optional owned box, `Option<Box<T>>`.
  58  //!
  59  //! The following example uses `Option` to create an optional box of
  60  //! `int`. Notice that in order to use the inner `int` value first the
  61  //! `check_optional` function needs to use pattern matching to
  62  //! determine whether the box has a value (i.e. it is `Some(...)`) or
  63  //! not (`None`).
  64  //!
  65  //! ```
  66  //! let optional: Option<Box<int>> = None;
  67  //! check_optional(&optional);
  68  //!
  69  //! let optional: Option<Box<int>> = Some(box 9000);
  70  //! check_optional(&optional);
  71  //!
  72  //! fn check_optional(optional: &Option<Box<int>>) {
  73  //!     match *optional {
  74  //!         Some(ref p) => println!("have value {}", p),
  75  //!         None => println!("have no value")
  76  //!     }
  77  //! }
  78  //! ```
  79  //!
  80  //! This usage of `Option` to create safe nullable pointers is so
  81  //! common that Rust does special optimizations to make the
  82  //! representation of `Option<Box<T>>` a single pointer. Optional pointers
  83  //! in Rust are stored as efficiently as any other pointer type.
  84  //!
  85  //! # Examples
  86  //!
  87  //! Basic pattern matching on `Option`:
  88  //!
  89  //! ```
  90  //! let msg = Some("howdy");
  91  //!
  92  //! // Take a reference to the contained string
  93  //! match msg {
  94  //!     Some(ref m) => println!("{}", *m),
  95  //!     None => ()
  96  //! }
  97  //!
  98  //! // Remove the contained string, destroying the Option
  99  //! let unwrapped_msg = match msg {
 100  //!     Some(m) => m,
 101  //!     None => "default message"
 102  //! };
 103  //! ```
 104  //!
 105  //! Initialize a result to `None` before a loop:
 106  //!
 107  //! ```
 108  //! enum Kingdom { Plant(uint, &'static str), Animal(uint, &'static str) }
 109  //!
 110  //! // A list of data to search through.
 111  //! let all_the_big_things = [
 112  //!     Plant(250, "redwood"),
 113  //!     Plant(230, "noble fir"),
 114  //!     Plant(229, "sugar pine"),
 115  //!     Animal(25, "blue whale"),
 116  //!     Animal(19, "fin whale"),
 117  //!     Animal(15, "north pacific right whale"),
 118  //! ];
 119  //!
 120  //! // We're going to search for the name of the biggest animal,
 121  //! // but to start with we've just got `None`.
 122  //! let mut name_of_biggest_animal = None;
 123  //! let mut size_of_biggest_animal = 0;
 124  //! for big_thing in all_the_big_things.iter() {
 125  //!     match *big_thing {
 126  //!         Animal(size, name) if size > size_of_biggest_animal => {
 127  //!             // Now we've found the name of some big animal
 128  //!             size_of_biggest_animal = size;
 129  //!             name_of_biggest_animal = Some(name);
 130  //!         }
 131  //!         Animal(..) | Plant(..) => ()
 132  //!     }
 133  //! }
 134  //!
 135  //! match name_of_biggest_animal {
 136  //!     Some(name) => println!("the biggest animal is {}", name),
 137  //!     None => println!("there are no animals :(")
 138  //! }
 139  //! ```
 140  
 141  use any::Any;
 142  use kinds::Send;
 143  
 144  pub use core::option::{Option, Some, None, Item, collect};
 145  
 146  /// Extension trait for the `Option` type to add an `expect` method
 147  
 148  // FIXME(#14008) should this trait even exist?
 149  pub trait Expect<T> {
 150      /// Unwraps an option, yielding the content of a `Some`
 151      ///
 152      /// # Failure
 153      ///
 154      /// Fails if the value is a `None` with a custom failure message provided by
 155      /// `msg`.
 156      fn expect<M: Any + Send>(self, m: M) -> T;
 157  }
 158  
 159  impl<T> Expect<T> for Option<T> {
 160      #[inline]
 161      fn expect<M: Any + Send>(self, msgM) -> T {
 162          match self {
 163              Some(val) => val,
 164              None => fail!(msg),
 165          }
 166      }
 167  }