Skip to content

Commit 8063450

Browse files
committed
auto merge of #12982 : brson/rust/optiondocs, r=alexcrichton
Various improvements. There's a lot more that can be done.
2 parents ff03335 + 8fcb8dd commit 8063450

File tree

1 file changed

+170
-20
lines changed

1 file changed

+170
-20
lines changed

src/libstd/option.rs

+170-20
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,86 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! Optionally nullable values (`Option` type)
11+
//! Optional values
1212
//!
13-
//! Type `Option` represents an optional value.
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:
1417
//!
15-
//! Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
16-
//! languages you might use a nullable type, in Rust you would use an option
17-
//! type.
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
1828
//!
19-
//! Options are most commonly used with pattern matching to query the presence
29+
//! Options are commonly paired with pattern matching to query the presence
2030
//! of a value and take action, always accounting for the `None` case.
2131
//!
22-
//! # Example
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);
2368
//!
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+
//! }
2478
//! ```
25-
//! let msg = Some(~"howdy");
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");
2691
//!
2792
//! // Take a reference to the contained string
2893
//! match msg {
@@ -33,9 +98,45 @@
3398
//! // Remove the contained string, destroying the Option
3499
//! let unwrapped_msg = match msg {
35100
//! Some(m) => m,
36-
//! None => ~"default message"
101+
//! None => "default message"
37102
//! };
38103
//! ```
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+
//! ```
39140
40141
use any::Any;
41142
use clone::Clone;
@@ -46,7 +147,7 @@ use kinds::Send;
46147
use mem;
47148
use vec;
48149

49-
/// The option type
150+
/// The `Option`
50151
#[deriving(Clone, Eq, Ord, TotalEq, TotalOrd, Show)]
51152
pub enum Option<T> {
52153
/// No value
@@ -64,7 +165,7 @@ impl<T> Option<T> {
64165
// Querying the contained values
65166
/////////////////////////////////////////////////////////////////////////
66167

67-
/// Returns true if the option contains a `Some` value
168+
/// Returns `true` if the option is a `Some` value
68169
#[inline]
69170
pub fn is_some(&self) -> bool {
70171
match *self {
@@ -73,7 +174,7 @@ impl<T> Option<T> {
73174
}
74175
}
75176

76-
/// Returns true if the option equals `None`
177+
/// Returns `true` if the option is a `None` value
77178
#[inline]
78179
pub fn is_none(&self) -> bool {
79180
!self.is_some()
@@ -84,6 +185,21 @@ impl<T> Option<T> {
84185
/////////////////////////////////////////////////////////////////////////
85186

86187
/// Convert from `Option<T>` to `Option<&T>`
188+
///
189+
/// # Example
190+
///
191+
/// Convert an `Option<~str>` into an `Option<int>`, preserving the original.
192+
/// The `map` method takes the `self` argument by value, consuming the original,
193+
/// so this technique uses `as_ref` to first take an `Option` to a reference
194+
/// to the value inside the original.
195+
///
196+
/// ```
197+
/// let num_as_str: Option<~str> = Some(~"10");
198+
/// // First, cast `Option<~str>` to `Option<&~str>` with `as_ref`,
199+
/// // then consume *that* with `map`, leaving `num_as_str` on the stack.
200+
/// let num_as_int: Option<uint> = num_as_str.as_ref().map(|n| n.len());
201+
/// println!("still can print num_as_str: {}", num_as_str);
202+
/// ```
87203
#[inline]
88204
pub fn as_ref<'r>(&'r self) -> Option<&'r T> {
89205
match *self { Some(ref x) => Some(x), None => None }
@@ -118,6 +234,9 @@ impl<T> Option<T> {
118234
/////////////////////////////////////////////////////////////////////////
119235

120236
/// Unwraps an option, yielding the content of a `Some`
237+
///
238+
/// # Failure
239+
///
121240
/// Fails if the value is a `None` with a custom failure message provided by `msg`.
122241
#[inline]
123242
pub fn expect<M: Any + Send>(self, msg: M) -> T {
@@ -127,14 +246,11 @@ impl<T> Option<T> {
127246
}
128247
}
129248

130-
/// Moves a value out of an option type and returns it.
131-
///
132-
/// Useful primarily for getting strings, vectors and unique pointers out
133-
/// of option types without copying them.
249+
/// Moves a value out of an option type and returns it, consuming the `Option`.
134250
///
135251
/// # Failure
136252
///
137-
/// Fails if the value equals `None`.
253+
/// Fails if the self value equals `None`.
138254
///
139255
/// # Safety note
140256
///
@@ -171,7 +287,17 @@ impl<T> Option<T> {
171287
// Transforming contained values
172288
/////////////////////////////////////////////////////////////////////////
173289

174-
/// Maps an `Option<T>` to `Option<U>` by applying a function to a contained value.
290+
/// Maps an `Option<T>` to `Option<U>` by applying a function to a contained value
291+
///
292+
/// # Example
293+
///
294+
/// Convert an `Option<~str>` into an `Option<uint>`, consuming the original:
295+
///
296+
/// ```
297+
/// let num_as_str: Option<~str> = Some(~"10");
298+
/// // `Option::map` takes self *by value*, consuming `num_as_str`
299+
/// let num_as_int: Option<uint> = num_as_str.map(|n| n.len());
300+
/// ```
175301
#[inline]
176302
pub fn map<U>(self, f: |T| -> U) -> Option<U> {
177303
match self { Some(x) => Some(f(x)), None => None }
@@ -359,7 +485,28 @@ impl<T> Option<T> {
359485
}
360486

361487
impl<T: Default> Option<T> {
362-
/// Returns the contained value or default (for this type)
488+
/// Returns the contained value or a default
489+
///
490+
/// Consumes the `self` argument then, if `Some`, returns the contained
491+
/// value, otherwise if `None`, returns the default value for that
492+
/// type.
493+
///
494+
/// # Example
495+
///
496+
/// Convert a string to an integer, turning poorly-formed strings
497+
/// into 0 (the default value for integers). `from_str` converts
498+
/// a string to any other type that implements `FromStr`, returning
499+
/// `None` on error.
500+
///
501+
/// ```
502+
/// let good_year_from_input = "1909";
503+
/// let bad_year_from_input = "190blarg";
504+
/// let good_year = from_str(good_year_from_input).unwrap_or_default();
505+
/// let bad_year = from_str(bad_year_from_input).unwrap_or_default();
506+
///
507+
/// assert_eq!(1909, good_year);
508+
/// assert_eq!(0, bad_year);
509+
/// ```
363510
#[inline]
364511
pub fn unwrap_or_default(self) -> T {
365512
match self {
@@ -382,7 +529,10 @@ impl<T> Default for Option<T> {
382529
// The Option Iterator
383530
/////////////////////////////////////////////////////////////////////////////
384531

385-
/// An iterator that yields either one or zero elements
532+
/// An `Option` iterator that yields either one or zero elements
533+
///
534+
/// The `Item` iterator is returned by the `iter`, `mut_iter` and `move_iter`
535+
/// methods on `Option`.
386536
#[deriving(Clone)]
387537
pub struct Item<A> {
388538
priv opt: Option<A>

0 commit comments

Comments
 (0)