2016-03-30 7 views
4

Ich habe die folgende Definition:Wie man PartialEq für eine Enum implementieren?

enum Either<T, U> { 
    Left(T), 
    Right(U) 
} 

Wie würde ich das Äquivalent von #[derive(PartialEq)] für diese Art bekommen? Ich möchte einen match Ausdruck verwenden, wie:

impl<T: PartialEq, U: PartialEq> PartialEq for Either<T, U> { 
    fn eq(&self, other: &Either<T, U>) -> bool { 
     match (*self, *other) { 
      (Left(ref a), Left(ref b)) => a == b, 
      (Right(ref a), Right(ref b)) => a == b, 
      _ => false, 
     } 
    } 
} 

aber dies verursacht einen Fehler cannot move out of borrowed content bei der Erstellung von (*self, *other) weil dies sowohl *self und *other verbraucht, auch wenn ich brauche es nur für das Spiel Ausdruck.

Antwort

8

Normalerweise würden Sie nur #[derive(PartialEq)] verwenden, etwa so:

#[derive(PartialEq)] 
enum Either<T, U> { 
    Left(T), 
    Right(U) 
} 

Dies wird den Code generieren für Sie das Merkmal zu implementieren.


Manchmal möchten Sie das Merkmal direkt implementieren. Dies kann daran liegen, dass die Standardversion entweder zu spezifisch oder zu allgemein ist.

Der Fehler in Ihrem Fall ist, dass Sie Sie die Referenzen übereinstimmen müssen Muster anstatt zu dereferenzieren sie versuchen:

impl<T: PartialEq, U: PartialEq> PartialEq for Either<T, U> { 
    fn eq(&self, other: &Either<T, U>) -> bool { 
     use Either::*; 

     match (self, other) { 
      (&Left(ref a), &Left(ref b)) => a == b, 
      (&Right(ref a), &Right(ref b)) => a == b, 
      _ => false, 
     } 
    } 
} 

Ich glaube, das liegt daran, dass, wenn Sie ein Tupel erstellen, würden Sie den dereferenzierten bewegen Element in das Tupel, Besitz aufgeben. Wenn Sie eine match *foo haben, müssen Sie die Eigentumsrechte nicht aufgeben.

+0

Warum wird '# [ableiten (PartialEq)]' nicht implementiert? – starblue

+0

@starblue Was meinst du? Soweit ich weiß, erzeugt '# [derived (PartialEq)]' LLVM direkt aus dem Compiler, so dass es keinen zu untersuchenden Rust-Code gibt. Ich wollte ein Impl erstellen, das so viel wie möglich als Basis für die Modifikation produziert. –

+2

Es produziert Rost-Code, Sie sehen es einfach nicht, weil es während der Kompilierung passiert, anstatt in der Quelle zu sein. –

Verwandte Themen