枚举触发器线程 'main' 的 PartialEQ 显式实现已溢出其堆栈

PartialEQ explicit implementation for enum triggers thread 'main' has overflowed its stack

枚举的 PartialEQ 的显式实现在具有带有枚举的数组的结构时触发堆栈溢出:

#[derive(Debug, Copy, Clone)]
enum MyEnum {
    A,
}

impl PartialEq for MyEnum {
    fn eq(&self, other: &Self) -> bool {
        self == other
    }
}

#[derive(Debug)]
struct MyStruct {
    cells: [MyEnum; 1],
}

fn main() {
    let init_struct = MyStruct {
        cells: [MyEnum::A]
    };

    assert_eq!(init_struct.cells[0], MyEnum::A);
}

终端输出:

➜  enum-bug git:(master) ✗ cargo run
   Compiling enum-bug v0.1.0 
    Finished dev [unoptimized + debuginfo] target(s) in 0.27s
     Running `target/debug/enum-bug`

thread 'main' has overflowed its stack
fatal runtime error: stack overflow
[1]    2361 abort      cargo run

但是当注释掉 PartialEQ 的显式实现,并将其添加到#[derive] 时一切正常:

#[derive(Debug, Copy, Clone, PartialEq)]
enum MyEnum {
    A,
}

/*
impl PartialEq for MyEnum {
    fn eq(&self, other: &Self) -> bool {
        self == other
    }
}
*/

#[derive(Debug)]
struct MyStruct {
    cells: [MyEnum; 1],
}

fn main() {
    let init_struct = MyStruct {
        cells: [MyEnum::A]
    };

    assert_eq!(init_struct.cells[0], MyEnum::A);
}

那么枚举的显式 PartialEQ 实现有什么问题?

正如其他人在评论中指出的那样,== 寻找 PartialEq 实现,因此您的代码会无限递归。

相反,您可以使用 match:

enum Foo {
  A,
  B,
}

impl PartialEq for Foo {
  fn eq(&self, other: &Self) -> bool {
    match (self, other) {
      (Self::A, Self::A) => true,
      (Self::B, Self::B) => true,
      _ => false
    }
  }
}

虽然我建议只为大多数 PartialEq 实现推导它,除非你有充分的理由不这样做。