这是indexloc提供的服务,不要输入任何密码
Skip to content

Appendix C: PartianEq and PartialOrd derived on enums #4551

@NeatNit

Description

@NeatNit
  • I have searched open and closed issues and pull requests for duplicates, using these search terms:
    • PartialEq
  • I have checked the latest main branch to see if this has already been fixed, in this file:
    • src/appendix-03-derivable-traits.md

URL to the section(s) of the book with this problem: https://doc.rust-lang.org/book/appendix-03-derivable-traits.html#partialeq-and-eq-for-equality-comparisons

Description of the problem:
These emphasized sections leave out a core detail:

Deriving PartialEq implements the eq method. When PartialEq is derived on structs, two instances are equal only if all fields are equal, and the instances are not equal if any fields are not equal. When derived on enums, each variant is equal to itself and not equal to the other variants.

When derived on structs, PartialOrd compares two instances by comparing the value in each field in the order in which the fields appear in the struct definition. When derived on enums, variants of the enum declared earlier in the enum definition are considered less than the variants listed later.

These descriptions don't mention that when comparing the same variant of an enum, the variant's attached data will be compared. For example:

#[derive(PartialEq, PartialOrd, Debug)]
enum MyEnum {
    A(i32),
    B(i32),
}

use MyEnum::*;

fn main() {
    let (a, b) = (A(0), A(0));
    println!("{a:?} {:?} {b:?}", a.partial_cmp(&b).unwrap());

    let (a, b) = (A(10), A(20));
    println!("{a:?} {:?} {b:?}", a.partial_cmp(&b).unwrap());

    let (a, b) = (B(0), B(0));
    println!("{a:?} {:?} {b:?}", a.partial_cmp(&b).unwrap());

    let (a, b) = (B(10), B(20));
    println!("{a:?} {:?} {b:?}", a.partial_cmp(&b).unwrap());

    let (a, b) = (A(0), B(0));
    println!("{a:?} {:?} {b:?}", a.partial_cmp(&b).unwrap());

    let (a, b) = (A(10), B(20));
    println!("{a:?} {:?} {b:?}", a.partial_cmp(&b).unwrap());

    let (a, b) = (A(20), B(10));
    println!("{a:?} {:?} {b:?}", a.partial_cmp(&b).unwrap());

}

Results in:

A(0) Equal A(0)
A(10) Less A(20)
B(0) Equal B(0)
B(10) Less B(20)
A(0) Less B(0)
A(10) Less B(20)
A(20) Less B(10)

The description in Appendix C implies that any A(...) will be equal to any other A(...), which is not the case!

Suggested fix:
Mention that attached values (is that what they're called?) are compared when the enums being compared are the same variant.

Permalink to current file:
https://github.com/rust-lang/book/blob/f660f341887c8bbcd6c24fbfdf5d2a262f523965/src/appendix-03-derivable-traits.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions