1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
//! Point me where I need to go
//!
//! - **Date:** August 5, 2016
//! - **Subject:** A deep dive on references and pointers in Rust.
//! - [**Audio**][mp3]
//!
//! [mp3]: https://www.podtrac.com/pts/redirect.mp3/cdn.newrustacean.com/file/newrustacean/e017.mp3
//!
//! <audio style="width: 100%" title="e017: Point me where I need to go" controls preload=metadata><source src="https://www.podtrac.com/pts/redirect.mp3/cdn.newrustacean.com/file/newrustacean/e017.mp3"></audio>
//!
//!
//! Notes
//! -----
//!
//! By listener request, today we look at the syntax and semantics of
//! referencing and dereferencing and the corresponding `&` and `*` operators.
//!
//! As was the case with [e016], the code samples have little to say in their
//! documentation; *reading* the code will be necessary for seeing the ideas.
//!
//! [e016]: http://newrustacean.dev/show_notes/e016/
//!
//!
//! Links
//! -----
//!
//! - ["Inside the Fastest Font Renderer in the World"][raph]
//! - The Rust Platform:
//! + [original blog post][blog]
//! * [Rust internals discussion][internals]
//! * [Reddit discussion][reddit1]
//! * [Hacker News discussion][hn1]
//! + [follow-up]
//! * [Reddit discussion][reddit2]
//! - [Cargo vendoring support in nightly][vendoring]
//! - [MIR on by default in nightly][MIR]
//! - References and dereferencing:
//! + _The Rust Programming Language_:
//! * [References and Borrowing][book:rab]
//! * [`Deref` coercions][book:deref]
//! + _Rust by Example_: [Flow Control: pointers/ref][rbe]
//! + The Rust Reference:
//! * [Unary Operator Expressions][uoe]
//! * [Pointer Types][pointer-types]
//!
//! [raph]: https://medium.com/@raphlinus/inside-the-fastest-font-renderer-in-the-world-75ae5270c445#.1opn7gihv
//! [blog]: http://aturon.github.io/blog/2016/07/27/rust-platform/
//! [internals]: https://internals.rust-lang.org/t/proposal-the-rust-platform/3745
//! [reddit1]: https://www.reddit.com/r/rust/comments/4uxdn8/the_rust_platform_aaron_turon/?
//! [hn1]: https://news.ycombinator.com/item?id=12177002
//! [follow-up]: https://internals.rust-lang.org/t/follow-up-the-rust-platform/3782
//! [reddit2]: https://www.reddit.com/r/rust/comments/4v9eo0/follow_up_to_the_rust_platform/?
//! [vendoring]: https://users.rust-lang.org/t/cargo-vendoring-now-on-nightly/6776
//! [MIR]: https://github.com/rust-lang/rust/pull/34096
//! [book:rab]: https://doc.rust-lang.org/book/references-and-borrowing.html
//! [book:deref]: https://doc.rust-lang.org/book/deref-coercions.html
//! [rbe]: http://rustbyexample.com/flow_control/match/destructuring/destructure_pointers.html
//! [uoe]: https://doc.rust-lang.org/reference.html#unary-operator-expressions
//! [pointer-types]: https://doc.rust-lang.org/reference.html#pointer-types
//!
//!
//! Sponsors
//! --------
//!
//! - Aleksey Pirogov
//! - Cameron Mochrie
//! - Cass Costello
//! - [Chris Palmer]
//! - [Daniel Collin]
//! - [Derek Morr]
//! - Doug Reeves
//! - Eric Fulmer
//! - Hamza Sheikh
//! - [Jakub "Limeth" Hlusička]
//! - [Jared Smith]
//! - Keith Gray
//! - Lachlan Collins
//! - Leif Arne Storset
//! - Luca Schmid
//! - Micael Bergeron
//! - [Pascal Hertleif]
//! - Ralph Giles ("rillian")
//! - Ralph "FriarTech" Loizzo
//! - Raph Levien
//! - reddraggone9
//! - Ryan Ollos
//! - Steven Murawski
//! - Vesa Kaihlavirta
//! - [William Roe]
//!
//! [Chris Palmer]: http://red-oxide.org/
//! [Daniel Collin]: twitter.com/daniel_collin
//! [Derek Morr]: https://twitter.com/derekmorr
//! [Jakub "Limeth" Hlusička]: https://github.com/Limeth
//! [Jared Smith]: http://twitter.com/jaredthecoder
//! [Pascal Hertleif]: https://pascalhertleif.de/
//! [William Roe]: http://willroe.me
//!
//! (Thanks to the couple people donating who opted out of the reward tier, as
//! well. You know who you are!)
//!
//! ### Become a sponsor
//!
//! - <a href="https://www.patreon.com/newrustacean" rel="payment">Patreon</a>
//! - [Venmo](https://venmo.com/chriskrycho)
//! - [Dwolla](https://www.dwolla.com/hub/chriskrycho)
//! - [Cash.me](https://cash.me/$chriskrycho)
//! - [Flattr](https://flattr.com/profile/chriskrycho)
//! - [PayPal.me](https://paypal.me/chriskrycho)
//!
//!
//! Contact
//! -------
//!
//! - New Rustacean:
//! + Twitter: [@newrustacean](https://www.twitter.com/newrustacean)
//! + Email: [hello@newrustacean.com](mailto:hello@newrustacean.com)
//! - Chris Krycho
//! + GitHub: [chriskrycho](https://github.com/chriskrycho)
//! + Twitter: [@chriskrycho](https://www.twitter.com/chriskrycho)
/// A dummy container for use with references.
pub struct DataStore<'a> {
pub contents: &'a i32,
}
impl<'a> DataStore<'a> {
pub fn new(contents: &'a i32) -> DataStore {
DataStore { contents }
}
}
/// Give a basic example of how the reference operator works.
pub fn demonstrate_ref() {
let twelve = 12;
let ref_twelve = &twelve;
// Both of these work because of the magic of automatic dereferencing, which
// we'll talk about next week.
println!("{:?}", twelve);
println!("{:?}", ref_twelve);
}
/// A simple example of using the dereference operator.
pub fn demonstrate_deref() {
// Note here we can create a reference right out of the gate, and pass it
// without applying the `&` operator again.
let forty_two_ref = &42;
let some_data = DataStore::new(forty_two_ref);
// As above! Note that the types are not the same, but dereferencing happens
// under the covers.
println!("{:}", some_data.contents);
println!("{:}", *some_data.contents);
}
/// A simple demonstration of matching against a reference type.
pub fn demonstrate_match() {
let four = 4;
let ref_to_four = &four;
// Here, if we try to reference the contents of `store` directly, we'll find
// that it doesn't work: we get a type error.
let store = DataStore::new(ref_to_four); // type: DataStore
let optional_store = Some(store); // type: Option<DataStore>
let contents = match optional_store {
Some(store) => *store.contents,
None => 0,
};
println!("{:?}", contents);
}