Skip to content

Commit 37275b6

Browse files
committed
improved std::hash::Hash docs
Part of #29357. * merged "Derivable" and "How can I implement `Hash`?" sections into one "Implementing `Hash`" section to aid coherency * added an example for `#[derive(Hash)]` * moved part about relation between `Hash` and `Eq` into a new "`Hash` and `Eq`" section; changed wording to be more consistent with `HashMap` and `HashSet`'s * explicitly mentioned `#[derive(PartialEq, Eq, Hash)]` in the new section * changed method summaries for consistency, adding links and examples
1 parent e88a511 commit 37275b6

File tree

1 file changed

+61
-22
lines changed

1 file changed

+61
-22
lines changed

src/libcore/hash/mod.rs

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -107,29 +107,25 @@ mod sip;
107107

108108
/// A hashable type.
109109
///
110-
/// The `H` type parameter is an abstract hash state that is used by the `Hash`
111-
/// to compute the hash.
110+
/// Types implementing `Hash` are able to be [`hash`]ed with an instance of
111+
/// [`Hasher`].
112112
///
113-
/// If you are also implementing [`Eq`], there is an additional property that
114-
/// is important:
113+
/// ## Implementing `Hash`
115114
///
116-
/// ```text
117-
/// k1 == k2 -> hash(k1) == hash(k2)
118-
/// ```
119-
///
120-
/// In other words, if two keys are equal, their hashes should also be equal.
121-
/// [`HashMap`] and [`HashSet`] both rely on this behavior.
115+
/// You can derive `Hash` with `#[derive(Hash)]` if all fields implement `Hash`.
116+
/// The resulting hash will be the combination of the values from calling
117+
/// [`hash`] on each field.
122118
///
123-
/// ## Derivable
124-
///
125-
/// This trait can be used with `#[derive]` if all fields implement `Hash`.
126-
/// When `derive`d, the resulting hash will be the combination of the values
127-
/// from calling [`.hash`] on each field.
128-
///
129-
/// ## How can I implement `Hash`?
119+
/// ```
120+
/// #[derive(Hash)]
121+
/// struct Rustacean {
122+
/// name: String,
123+
/// country: String,
124+
/// }
125+
/// ```
130126
///
131-
/// If you need more control over how a value is hashed, you need to implement
132-
/// the `Hash` trait:
127+
/// If you need more control over how a value is hash, you can of course
128+
/// implement the `Hash` trait yourself:
133129
///
134130
/// ```
135131
/// use std::hash::{Hash, Hasher};
@@ -148,17 +144,60 @@ mod sip;
148144
/// }
149145
/// ```
150146
///
147+
/// ## `Hash` and `Eq`
148+
///
149+
/// When implementing both `Hash` and [`Eq`], it is important that the following
150+
/// property holds:
151+
///
152+
/// ```text
153+
/// k1 == k2 -> hash(k1) == hash(k2)
154+
/// ```
155+
///
156+
/// In other words, if two keys are equal, their hashes must also be equal.
157+
/// [`HashMap`] and [`HashSet`] both rely on this behavior.
158+
///
159+
/// Thankfully, you won't need to worry about upholding this property when
160+
/// deriving both [`Eq`] and `Hash` with `#[derive(PartialEq, Eq, Hash)]`.
161+
///
151162
/// [`Eq`]: ../../std/cmp/trait.Eq.html
163+
/// [`Hasher`]: trait.Hasher.html
152164
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
153165
/// [`HashSet`]: ../../std/collections/struct.HashSet.html
154-
/// [`.hash`]: #tymethod.hash
166+
/// [`hash`]: #tymethod.hash
155167
#[stable(feature = "rust1", since = "1.0.0")]
156168
pub trait Hash {
157-
/// Feeds this value into the state given, updating the hasher as necessary.
169+
/// Feeds this value into the given [`Hasher`].
170+
///
171+
/// # Examples
172+
///
173+
/// ```
174+
/// use std::collections::hash_map::DefaultHasher;
175+
/// use std::hash::{Hash, Hasher};
176+
///
177+
/// let mut hasher = DefaultHasher::new();
178+
/// 7920.hash(&mut hasher);
179+
/// println!("Hash is {:x}!", hasher.finish());
180+
/// ```
181+
///
182+
/// [`Hasher`]: trait.Hasher.html
158183
#[stable(feature = "rust1", since = "1.0.0")]
159184
fn hash<H: Hasher>(&self, state: &mut H);
160185

161-
/// Feeds a slice of this type into the state provided.
186+
/// Feeds a slice of this type into the given [`Hasher`].
187+
///
188+
/// # Examples
189+
///
190+
/// ```
191+
/// use std::collections::hash_map::DefaultHasher;
192+
/// use std::hash::{Hash, Hasher};
193+
///
194+
/// let mut hasher = DefaultHasher::new();
195+
/// let numbers = [6, 28, 496, 8128];
196+
/// Hash::hash_slice(&numbers, &mut hasher);
197+
/// println!("Hash is {:x}!", hasher.finish());
198+
/// ```
199+
///
200+
/// [`Hasher`]: trait.Hasher.html
162201
#[stable(feature = "hash_slice", since = "1.3.0")]
163202
fn hash_slice<H: Hasher>(data: &[Self], state: &mut H)
164203
where Self: Sized

0 commit comments

Comments
 (0)