]> git.lizzy.rs Git - rust.git/blob - src/libstd/option.rs
core: Move Option::expect to libstd from libcore
[rust.git] / src / libstd / option.rs
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<~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<~int> = None;
67 //! check_optional(&optional);
68 //!
69 //! let optional: Option<~int> = Some(~9000);
70 //! check_optional(&optional);
71 //!
72 //! fn check_optional(optional: &Option<~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<~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 }