Skip to content

Commit b1a64e8

Browse files
authored
Merge pull request #16177 from lorentey/hashable-docs
[SE-0206] Update Hashable docs for hash(into:)
2 parents 19c3c14 + 5d259cf commit b1a64e8

File tree

2 files changed

+39
-38
lines changed

2 files changed

+39
-38
lines changed

stdlib/public/core/Hashable.swift

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,27 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
/// A type that provides an integer hash value.
14-
///
15-
/// You can use any type that conforms to the `Hashable` protocol in a set or
16-
/// as a dictionary key. Many types in the standard library conform to
17-
/// `Hashable`: Strings, integers, floating-point and Boolean values, and even
18-
/// sets provide a hash value by default. Your own custom types can be
19-
/// hashable as well. When you define an enumeration without associated
20-
/// values, it gains `Hashable` conformance automatically, and you can add
21-
/// `Hashable` conformance to your other custom types by adding a single
22-
/// `hashValue` property.
23-
///
24-
/// A hash value, provided by a type's `hashValue` property, is an integer that
25-
/// is the same for any two instances that compare equally. That is, for two
26-
/// instances `a` and `b` of the same type, if `a == b`, then
27-
/// `a.hashValue == b.hashValue`. The reverse is not true: Two instances with
28-
/// equal hash values are not necessarily equal to each other.
29-
///
30-
/// - Important: Hash values are not guaranteed to be equal across different
31-
/// executions of your program. Do not save hash values to use in a future
32-
/// execution.
13+
/// A type that can be hashed into a `Hasher` to produce an integer hash value.
14+
///
15+
/// You can use any type that conforms to the `Hashable` protocol in a set or as
16+
/// a dictionary key. Many types in the standard library conform to `Hashable`:
17+
/// Strings, integers, floating-point and Boolean values, and even sets are
18+
/// hashable by default. Some other types, such as optionals, arrays and ranges
19+
/// automatically become hashable when their type arguments implement the same.
20+
///
21+
/// Your own custom types can be hashable as well. When you define an
22+
/// enumeration without associated values, it gains `Hashable` conformance
23+
/// automatically, and you can add `Hashable` conformance to your other custom
24+
/// types by implementing the `hash(into:)` method. For structs whose stored
25+
/// properties are all `Hashable`, and for enum types that have all-`Hashable`
26+
/// associated values, the compiler is able to provide an implementation of
27+
/// `hash(into:)` automatically.
28+
///
29+
/// Hashing a value means feeding its essential components into a hash function,
30+
/// represented by the `Hasher` type. Essential components are those that
31+
/// contribute to the type's implementation of `Equatable`. Two instances that
32+
/// are equal must feed the same values to `Hasher` in `hash(into:)`, in the
33+
/// same order.
3334
///
3435
/// Conforming to the Hashable Protocol
3536
/// ===================================
@@ -50,10 +51,10 @@
5051
///
5152
/// To customize your type's `Hashable` conformance, to adopt `Hashable` in a
5253
/// type that doesn't meet the criteria listed above, or to extend an existing
53-
/// type to conform to `Hashable`, implement the `hashValue` property in your
54-
/// custom type. To ensure that your type meets the semantic requirements of
55-
/// the `Hashable` and `Equatable` protocols, it's a good idea to also
56-
/// customize your type's `Equatable` conformance to match.
54+
/// type to conform to `Hashable`, implement the `hash(into:)` function in your
55+
/// custom type. To ensure that your type meets the semantic requirements of the
56+
/// `Hashable` and `Equatable` protocols, it's a good idea to also customize
57+
/// your type's `Equatable` conformance to match the `hash(into:)` definition.
5758
///
5859
/// As an example, consider a `GridPoint` type that describes a location in a
5960
/// grid of buttons. Here's the initial declaration of the `GridPoint` type:
@@ -67,28 +68,25 @@
6768
/// You'd like to create a set of the grid points where a user has already
6869
/// tapped. Because the `GridPoint` type is not hashable yet, it can't be used
6970
/// as the `Element` type for a set. To add `Hashable` conformance, provide an
70-
/// `==` operator function and a `hashValue` property.
71+
/// `==` operator function and a `hash(into:)` method.
7172
///
7273
/// extension GridPoint: Hashable {
73-
/// var hashValue: Int {
74-
/// return x.hashValue ^ y.hashValue &* 16777619
75-
/// }
76-
///
7774
/// static func == (lhs: GridPoint, rhs: GridPoint) -> Bool {
7875
/// return lhs.x == rhs.x && lhs.y == rhs.y
7976
/// }
77+
///
78+
/// func hash(into hasher: inout Hasher) {
79+
/// hasher.combine(x)
80+
/// hasher.combine(y)
81+
/// }
8082
/// }
8183
///
82-
/// The `hashValue` property in this example combines the hash value of a grid
83-
/// point's `x` property with the hash value of its `y` property multiplied by
84-
/// a prime constant.
84+
/// The `hash(into:)` method in this example feeds the properties `x` and `y`
85+
/// to the supplied hasher; these are the same properties compared by the
86+
/// implementation of the `==` operator function.
8587
///
86-
/// - Note: The example above is a reasonably good hash function for a
87-
/// simple type. If you're writing a hash function for a custom type, choose
88-
/// a hashing algorithm that is appropriate for the kinds of data your type
89-
/// comprises. Set and dictionary performance depends on hash values that
90-
/// minimize collisions for their associated element and key types,
91-
/// respectively.
88+
/// (Because `x` and `y` are both `Hashable` themselves, you could've also let
89+
/// the compiler synthesize these implementations for you.)
9290
///
9391
/// Now that `GridPoint` conforms to the `Hashable` protocol, you can create a
9492
/// set of previously tapped grid points.

stdlib/public/core/Hasher.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,9 @@ public struct Hasher {
388388
/// Finalizing consumes the hasher: it is illegal to finalize a hasher you
389389
/// don't own, or to perform operations on a finalized hasher. (These may
390390
/// become compile-time errors in the future.)
391+
///
392+
/// Hash values are not guaranteed to be equal across different executions of
393+
/// your program. Do not save hash values to use during a future execution.
391394
@effects(releasenone)
392395
public __consuming func finalize() -> Int {
393396
var core = _core

0 commit comments

Comments
 (0)