@@ -53,12 +53,43 @@ use option::Option::{self, Some};
5353/// symmetrically and transitively: if `T: PartialEq<U>` and `U: PartialEq<V>`
5454/// then `U: PartialEq<T>` and `T: PartialEq<V>`.
5555///
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+ ///
5665/// PartialEq only requires the `eq` method to be implemented; `ne` is defined
5766/// in terms of it by default. Any manual implementation of `ne` *must* respect
5867/// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and
5968/// only if `a != b`.
6069///
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+ /// ```
6293///
6394/// # Examples
6495///
@@ -96,7 +127,32 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
96127/// This property cannot be checked by the compiler, and therefore `Eq` implies
97128/// `PartialEq`, and has no extra methods.
98129///
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+ /// ```
100156#[ stable( feature = "rust1" , since = "1.0.0" ) ]
101157pub trait Eq : PartialEq < Self > {
102158 // FIXME #13101: this method is used solely by #[deriving] to
@@ -190,8 +246,49 @@ impl Ordering {
190246/// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true; and
191247/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
192248///
249+ /// ## Derivable
250+ ///
193251/// This trait can be used with `#[derive]`. When `derive`d, it will produce a lexicographic
194252/// 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+ /// ```
195292#[ stable( feature = "rust1" , since = "1.0.0" ) ]
196293pub trait Ord : Eq + PartialOrd < Self > {
197294 /// This method returns an `Ordering` between `self` and `other`.
@@ -242,15 +339,78 @@ impl PartialOrd for Ordering {
242339/// transitively: if `T: PartialOrd<U>` and `U: PartialOrd<V>` then `U: PartialOrd<T>` and `T:
243340/// PartialOrd<V>`.
244341///
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+ ///
245349/// PartialOrd only requires implementation of the `partial_cmp` method, with the others generated
246350/// from default implementations.
247351///
248352/// However it remains possible to implement the others separately for types which do not have a
249353/// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 ==
250354/// false` (cf. IEEE 754-2008 section 5.11).
251355///
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+ /// ```
254414///
255415/// # Examples
256416///
0 commit comments