|
| 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 | +} |
0 commit comments