Content-Length: 27992 | pFad | https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#213-215

borrow.rs - source

core/
borrow.rs

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








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://doc.rust-lang.org/nightly/src/core/borrow.rs.html#213-215

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy