(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, msg: M) -> T {
162 match self {
163 Some(val) => val,
164 None => fail!(msg),
165 }
166 }
167 }