]> git.lizzy.rs Git - rust.git/blob - src/libcore/borrow.rs
Merge branch 'master' of https://github.com/rust-lang/rust into e0389
[rust.git] / src / libcore / borrow.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 //! A module for working with borrowed data.
12
13 #![stable(feature = "rust1", since = "1.0.0")]
14
15 /// A trait for borrowing data.
16 ///
17 /// In Rust, it is common to provide different representations of a type for
18 /// different use cases. For instance, storage location and management for a
19 /// value can be specifically chosen as appropriate for a particular use via
20 /// pointer types such as [`Box<T>`] or [`Rc<T>`]. Beyond these generic
21 /// wrappers that can be used with any type, some types provide optional
22 /// facets providing potentially costly functionality. An example for such a
23 /// type is [`String`] which adds the ability to extend a string to the basic
24 /// [`str`]. This requires keeping additional information unnecessary for a
25 /// simple, immutable string.
26 ///
27 /// These types provide access to the underlying data through references
28 /// to the type of that data. They are said to be ‘borrowed as’ that type.
29 /// For instance, a [`Box<T>`] can be borrowed as `T` while a [`String`]
30 /// can be borrowed as `str`.
31 ///
32 /// Types express that they can be borrowed as some type `T` by implementing
33 /// `Borrow<T>`, providing a reference to a `T` in the trait’s
34 /// [`borrow`] method. A type is free to borrow as several different types.
35 /// If it wishes to mutably borrow as the type – allowing the underlying data
36 /// to be modified, it can additionally implement [`BorrowMut<T>`].
37 ///
38 /// Further, when providing implementations for additional traits, it needs
39 /// to be considered whether they should behave identical to those of the
40 /// underlying type as a consequence of acting as a representation of that
41 /// underlying type. Generic code typically uses `Borrow<T>` when it relies
42 /// on the identical behavior of these additional trait implementations.
43 /// These traits will likely appear as additional trait bounds.
44 ///
45 /// If generic code merely needs to work for all types that can
46 /// provide a reference to related type `T`, it is often better to use
47 /// [`AsRef<T>`] as more types can safely implement it.
48 ///
49 /// [`AsRef<T>`]: ../../std/convert/trait.AsRef.html
50 /// [`BorrowMut<T>`]: trait.BorrowMut.html
51 /// [`Box<T>`]: ../../std/boxed/struct.Box.html
52 /// [`Mutex<T>`]: ../../std/sync/struct.Mutex.html
53 /// [`Rc<T>`]: ../../std/rc/struct.Rc.html
54 /// [`str`]: ../../std/primitive.str.html
55 /// [`String`]: ../../std/string/struct.String.html
56 /// [`borrow`]: #tymethod.borrow
57 ///
58 /// # Examples
59 ///
60 /// As a data collection, [`HashMap<K, V>`] owns both keys and values. If
61 /// the key’s actual data is wrapped in a managing type of some kind, it
62 /// should, however, still be possible to search for a value using a
63 /// reference to the key’s data. For instance, if the key is a string, then
64 /// it is likely stored with the hash map as a [`String`], while it should
65 /// be possible to search using a [`&str`][`str`]. Thus, `insert` needs to
66 /// operate on a `String` while `get` needs to be able to use a `&str`.
67 ///
68 /// Slightly simplified, the relevant parts of `HashMap<K, V>` look like
69 /// this:
70 ///
71 /// ```
72 /// use std::borrow::Borrow;
73 /// use std::hash::Hash;
74 ///
75 /// pub struct HashMap<K, V> {
76 ///     # marker: ::std::marker::PhantomData<(K, V)>,
77 ///     // fields omitted
78 /// }
79 ///
80 /// impl<K, V> HashMap<K, V> {
81 ///     pub fn insert(&self, key: K, value: V) -> Option<V>
82 ///     where K: Hash + Eq
83 ///     {
84 ///         # unimplemented!()
85 ///         // ...
86 ///     }
87 ///
88 ///     pub fn get<Q>(&self, k: &Q) -> Option<&V>
89 ///     where
90 ///         K: Borrow<Q>,
91 ///         Q: Hash + Eq + ?Sized
92 ///     {
93 ///         # unimplemented!()
94 ///         // ...
95 ///     }
96 /// }
97 /// ```
98 ///
99 /// The entire hash map is generic over a key type `K`. Because these keys
100 /// are stored with the hash map, this type has to own the key’s data.
101 /// When inserting a key-value pair, the map is given such a `K` and needs
102 /// to find the correct hash bucket and check if the key is already present
103 /// based on that `K`. It therefore requires `K: Hash + Eq`.
104 ///
105 /// When searching for a value in the map, however, having to provide a
106 /// reference to a `K` as the key to search for would require to always
107 /// create such an owned value. For string keys, this would mean a `String`
108 /// value needs to be created just for the search for cases where only a
109 /// `str` is available.
110 ///
111 /// Instead, the `get` method is generic over the type of the underlying key
112 /// data, called `Q` in the method signature above. It states that `K`
113 /// borrows as a `Q` by requiring that `K: Borrow<Q>`. By additionally
114 /// requiring `Q: Hash + Eq`, it signals the requirement that `K` and `Q`
115 /// have implementations of the `Hash` and `Eq` traits that produce identical
116 /// results.
117 ///
118 /// The implementation of `get` relies in particular on identical
119 /// implementations of `Hash` by determining the key’s hash bucket by calling
120 /// `Hash::hash` on the `Q` value even though it inserted the key based on
121 /// the hash value calculated from the `K` value.
122 ///
123 /// As a consequence, the hash map breaks if a `K` wrapping a `Q` value
124 /// produces a different hash than `Q`. For instance, imagine you have a
125 /// type that wraps a string but compares ASCII letters ignoring their case:
126 ///
127 /// ```
128 /// pub struct CaseInsensitiveString(String);
129 ///
130 /// impl PartialEq for CaseInsensitiveString {
131 ///     fn eq(&self, other: &Self) -> bool {
132 ///         self.0.eq_ignore_ascii_case(&other.0)
133 ///     }
134 /// }
135 ///
136 /// impl Eq for CaseInsensitiveString { }
137 /// ```
138 ///
139 /// Because two equal values need to produce the same hash value, the
140 /// implementation of `Hash` needs to ignore ASCII case, too:
141 ///
142 /// ```
143 /// # use std::hash::{Hash, Hasher};
144 /// # pub struct CaseInsensitiveString(String);
145 /// impl Hash for CaseInsensitiveString {
146 ///     fn hash<H: Hasher>(&self, state: &mut H) {
147 ///         for c in self.0.as_bytes() {
148 ///             c.to_ascii_lowercase().hash(state)
149 ///         }
150 ///     }
151 /// }
152 /// ```
153 ///
154 /// Can `CaseInsensitiveString` implement `Borrow<str>`? It certainly can
155 /// provide a reference to a string slice via its contained owned string.
156 /// But because its `Hash` implementation differs, it behaves differently
157 /// from `str` and therefore must not, in fact, implement `Borrow<str>`.
158 /// If it wants to allow others access to the underlying `str`, it can do
159 /// that via `AsRef<str>` which doesn’t carry any extra requirements.
160 ///
161 /// [`Hash`]: ../../std/hash/trait.Hash.html
162 /// [`HashMap<K, V>`]: ../../std/collections/struct.HashMap.html
163 /// [`String`]: ../../std/string/struct.String.html
164 /// [`str`]: ../../std/primitive.str.html
165 #[stable(feature = "rust1", since = "1.0.0")]
166 pub trait Borrow<Borrowed: ?Sized> {
167     /// Immutably borrows from an owned value.
168     ///
169     /// # Examples
170     ///
171     /// ```
172     /// use std::borrow::Borrow;
173     ///
174     /// fn check<T: Borrow<str>>(s: T) {
175     ///     assert_eq!("Hello", s.borrow());
176     /// }
177     ///
178     /// let s = "Hello".to_string();
179     ///
180     /// check(s);
181     ///
182     /// let s = "Hello";
183     ///
184     /// check(s);
185     /// ```
186     #[stable(feature = "rust1", since = "1.0.0")]
187     fn borrow(&self) -> &Borrowed;
188 }
189
190 /// A trait for mutably borrowing data.
191 ///
192 /// As a companion to [`Borrow<T>`] this trait allows a type to borrow as
193 /// an underlying type by providing a mutable reference. See [`Borrow<T>`]
194 /// for more information on borrowing as another type.
195 ///
196 /// [`Borrow<T>`]: trait.Borrow.html
197 #[stable(feature = "rust1", since = "1.0.0")]
198 pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
199     /// Mutably borrows from an owned value.
200     ///
201     /// # Examples
202     ///
203     /// ```
204     /// use std::borrow::BorrowMut;
205     ///
206     /// fn check<T: BorrowMut<[i32]>>(mut v: T) {
207     ///     assert_eq!(&mut [1, 2, 3], v.borrow_mut());
208     /// }
209     ///
210     /// let v = vec![1, 2, 3];
211     ///
212     /// check(v);
213     /// ```
214     #[stable(feature = "rust1", since = "1.0.0")]
215     fn borrow_mut(&mut self) -> &mut Borrowed;
216 }
217
218 #[stable(feature = "rust1", since = "1.0.0")]
219 impl<T: ?Sized> Borrow<T> for T {
220     fn borrow(&self) -> &T { self }
221 }
222
223 #[stable(feature = "rust1", since = "1.0.0")]
224 impl<T: ?Sized> BorrowMut<T> for T {
225     fn borrow_mut(&mut self) -> &mut T { self }
226 }
227
228 #[stable(feature = "rust1", since = "1.0.0")]
229 impl<'a, T: ?Sized> Borrow<T> for &'a T {
230     fn borrow(&self) -> &T { &**self }
231 }
232
233 #[stable(feature = "rust1", since = "1.0.0")]
234 impl<'a, T: ?Sized> Borrow<T> for &'a mut T {
235     fn borrow(&self) -> &T { &**self }
236 }
237
238 #[stable(feature = "rust1", since = "1.0.0")]
239 impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
240     fn borrow_mut(&mut self) -> &mut T { &mut **self }
241 }