@@ -53,12 +53,43 @@ use option::Option::{self, Some};
53
53
/// symmetrically and transitively: if `T: PartialEq<U>` and `U: PartialEq<V>`
54
54
/// then `U: PartialEq<T>` and `T: PartialEq<V>`.
55
55
///
56
+ /// ## Derivable
57
+ ///
58
+ /// This trait can be used with `#[derive]`. When `derive`d on structs, two
59
+ /// instances are equal if all fields are equal, and not equal if any fields
60
+ /// are not equal. When `derive`d on enums, each variant is equal to itself
61
+ /// and not equal to the other variants.
62
+ ///
63
+ /// ## How can I implement `PartialEq`?
64
+ ///
56
65
/// PartialEq only requires the `eq` method to be implemented; `ne` is defined
57
66
/// in terms of it by default. Any manual implementation of `ne` *must* respect
58
67
/// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and
59
68
/// only if `a != b`.
60
69
///
61
- /// This trait can be used with `#[derive]`.
70
+ /// An example implementation for a domain in which two books are considered
71
+ /// the same book if their ISBN matches, even if the formats differ:
72
+ ///
73
+ /// ```
74
+ /// enum BookFormat { Paperback, Hardback, Ebook }
75
+ /// struct Book {
76
+ /// isbn: i32,
77
+ /// format: BookFormat,
78
+ /// }
79
+ ///
80
+ /// impl PartialEq for Book {
81
+ /// fn eq(&self, other: &Book) -> bool {
82
+ /// self.isbn == other.isbn
83
+ /// }
84
+ /// }
85
+ ///
86
+ /// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
87
+ /// let b2 = Book { isbn: 3, format: BookFormat::Ebook };
88
+ /// let b3 = Book { isbn: 10, format: BookFormat::Paperback };
89
+ ///
90
+ /// assert!(b1 == b2);
91
+ /// assert!(b1 != b3);
92
+ /// ```
62
93
///
63
94
/// # Examples
64
95
///
@@ -96,7 +127,32 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
96
127
/// This property cannot be checked by the compiler, and therefore `Eq` implies
97
128
/// `PartialEq`, and has no extra methods.
98
129
///
99
- /// This trait can be used with `#[derive]`.
130
+ /// ## Derivable
131
+ ///
132
+ /// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has
133
+ /// no extra methods, it is only informing the compiler that this is an
134
+ /// equivalence relation rather than a partial equivalence relation. Note that
135
+ /// the `derive` strategy requires all fields are `PartialEq`, which isn't
136
+ /// always desired.
137
+ ///
138
+ /// ## How can I implement `Eq`?
139
+ ///
140
+ /// If you cannot use the `derive` strategy, specify that your type implements
141
+ /// `Eq`, which has no methods:
142
+ ///
143
+ /// ```
144
+ /// enum BookFormat { Paperback, Hardback, Ebook }
145
+ /// struct Book {
146
+ /// isbn: i32,
147
+ /// format: BookFormat,
148
+ /// }
149
+ /// impl PartialEq for Book {
150
+ /// fn eq(&self, other: &Book) -> bool {
151
+ /// self.isbn == other.isbn
152
+ /// }
153
+ /// }
154
+ /// impl Eq for Book {}
155
+ /// ```
100
156
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
101
157
pub trait Eq : PartialEq < Self > {
102
158
// FIXME #13101: this method is used solely by #[deriving] to
@@ -190,8 +246,49 @@ impl Ordering {
190
246
/// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true; and
191
247
/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
192
248
///
249
+ /// ## Derivable
250
+ ///
193
251
/// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
194
252
/// ordering based on the top-to-bottom declaration order of the struct's members.
253
+ ///
254
+ /// ## How can I implement `Ord`?
255
+ ///
256
+ /// `Ord` requires that the type also be `PartialOrd` and `Eq` (which requires `PartialEq`).
257
+ ///
258
+ /// Then you must define an implementation for `cmp()`. You may find it useful to use
259
+ /// `cmp()` on your type's fields.
260
+ ///
261
+ /// Here's an example where you want to sort people by height only, disregarding `id`
262
+ /// and `name`:
263
+ ///
264
+ /// ```
265
+ /// use std::cmp::Ordering;
266
+ ///
267
+ /// #[derive(Eq)]
268
+ /// struct Person {
269
+ /// id: u32,
270
+ /// name: String,
271
+ /// height: u32,
272
+ /// }
273
+ ///
274
+ /// impl Ord for Person {
275
+ /// fn cmp(&self, other: &Person) -> Ordering {
276
+ /// self.height.cmp(&other.height)
277
+ /// }
278
+ /// }
279
+ ///
280
+ /// impl PartialOrd for Person {
281
+ /// fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
282
+ /// Some(self.cmp(other))
283
+ /// }
284
+ /// }
285
+ ///
286
+ /// impl PartialEq for Person {
287
+ /// fn eq(&self, other: &Person) -> bool {
288
+ /// self.height == other.height
289
+ /// }
290
+ /// }
291
+ /// ```
195
292
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
196
293
pub trait Ord : Eq + PartialOrd < Self > {
197
294
/// This method returns an `Ordering` between `self` and `other`.
@@ -242,15 +339,78 @@ impl PartialOrd for Ordering {
242
339
/// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
243
340
/// PartialOrd<V>`.
244
341
///
342
+ /// ## Derivable
343
+ ///
344
+ /// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
345
+ /// ordering based on the top-to-bottom declaration order of the struct's members.
346
+ ///
347
+ /// ## How can I implement `Ord`?
348
+ ///
245
349
/// PartialOrd only requires implementation of the `partial_cmp` method, with the others generated
246
350
/// from default implementations.
247
351
///
248
352
/// However it remains possible to implement the others separately for types which do not have a
249
353
/// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 ==
250
354
/// false` (cf. IEEE 754-2008 section 5.11).
251
355
///
252
- /// This trait can be used with `#[derive]`. When `derive`d, it will produce an ordering
253
- /// based on the top-to-bottom declaration order of the struct's members.
356
+ /// `PartialOrd` requires your type to be `PartialEq`.
357
+ ///
358
+ /// If your type is `Ord`, you can implement `partial_cmp()` by using `cmp()`:
359
+ ///
360
+ /// ```
361
+ /// use std::cmp::Ordering;
362
+ ///
363
+ /// #[derive(Eq)]
364
+ /// struct Person {
365
+ /// id: u32,
366
+ /// name: String,
367
+ /// height: u32,
368
+ /// }
369
+ ///
370
+ /// impl PartialOrd for Person {
371
+ /// fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
372
+ /// Some(self.cmp(other))
373
+ /// }
374
+ /// }
375
+ ///
376
+ /// impl Ord for Person {
377
+ /// fn cmp(&self, other: &Person) -> Ordering {
378
+ /// self.height.cmp(&other.height)
379
+ /// }
380
+ /// }
381
+ ///
382
+ /// impl PartialEq for Person {
383
+ /// fn eq(&self, other: &Person) -> bool {
384
+ /// self.height == other.height
385
+ /// }
386
+ /// }
387
+ /// ```
388
+ ///
389
+ /// You may also find it useful to use `partial_cmp()` on your type`s fields. Here
390
+ /// is an example of `Person` types who have a floating-point `height` field that
391
+ /// is the only field to be used for sorting:
392
+ ///
393
+ /// ```
394
+ /// use std::cmp::Ordering;
395
+ ///
396
+ /// struct Person {
397
+ /// id: u32,
398
+ /// name: String,
399
+ /// height: f64,
400
+ /// }
401
+ ///
402
+ /// impl PartialOrd for Person {
403
+ /// fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
404
+ /// self.height.partial_cmp(&other.height)
405
+ /// }
406
+ /// }
407
+ ///
408
+ /// impl PartialEq for Person {
409
+ /// fn eq(&self, other: &Person) -> bool {
410
+ /// self.height == other.height
411
+ /// }
412
+ /// }
413
+ /// ```
254
414
///
255
415
/// # Examples
256
416
///
0 commit comments