Trait wasmer_types::lib::std::cmp::PartialEq 1.0.0[−][src]
pub trait PartialEq<Rhs = Self> where
Rhs: ?Sized, { fn eq(&self, other: &Rhs) -> bool; fn ne(&self, other: &Rhs) -> bool { ... } }
Expand description
Trait for equality comparisons which are partial equivalence relations.
This trait allows for partial equality, for types that do not have a full
equivalence relation. For example, in floating point numbers NaN != NaN
,
so floating point types implement PartialEq
but not Eq
.
Formally, the equality must be (for all a
, b
, c
of type A
, B
,
C
):
-
Symmetric: if
A: PartialEq<B>
andB: PartialEq<A>
, thena == b
impliesb == a
; and -
Transitive: if
A: PartialEq<B>
andB: PartialEq<C>
andA: PartialEq<C>
, thena == b
andb == c
impliesa == c
.
Note that the B: PartialEq<A>
(symmetric) and A: PartialEq<C>
(transitive) impls are not forced to exist, but these requirements apply
whenever they do exist.
Derivable
This trait can be used with #[derive]
. When derive
d on structs, two
instances are equal if all fields are equal, and not equal if any fields
are not equal. When derive
d on enums, each variant is equal to itself
and not equal to the other variants.
How can I implement PartialEq
?
PartialEq
only requires the eq
method to be implemented; ne
is defined
in terms of it by default. Any manual implementation of ne
must respect
the rule that eq
is a strict inverse of ne
; that is, !(a == b)
if and
only if a != b
.
Implementations of PartialEq
, PartialOrd
, and Ord
must agree with
each other. It’s easy to accidentally make them disagree by deriving some
of the traits and manually implementing others.
An example implementation for a domain in which two books are considered the same book if their ISBN matches, even if the formats differ:
enum BookFormat { Paperback, Hardback, Ebook, } struct Book { isbn: i32, format: BookFormat, } impl PartialEq for Book { fn eq(&self, other: &Self) -> bool { self.isbn == other.isbn } } let b1 = Book { isbn: 3, format: BookFormat::Paperback }; let b2 = Book { isbn: 3, format: BookFormat::Ebook }; let b3 = Book { isbn: 10, format: BookFormat::Paperback }; assert!(b1 == b2); assert!(b1 != b3);
How can I compare two different types?
The type you can compare with is controlled by PartialEq
’s type parameter.
For example, let’s tweak our previous code a bit:
// The derive implements <BookFormat> == <BookFormat> comparisons #[derive(PartialEq)] enum BookFormat { Paperback, Hardback, Ebook, } struct Book { isbn: i32, format: BookFormat, } // Implement <Book> == <BookFormat> comparisons impl PartialEq<BookFormat> for Book { fn eq(&self, other: &BookFormat) -> bool { self.format == *other } } // Implement <BookFormat> == <Book> comparisons impl PartialEq<Book> for BookFormat { fn eq(&self, other: &Book) -> bool { *self == other.format } } let b1 = Book { isbn: 3, format: BookFormat::Paperback }; assert!(b1 == BookFormat::Paperback); assert!(BookFormat::Ebook != b1);
By changing impl PartialEq for Book
to impl PartialEq<BookFormat> for Book
,
we allow BookFormat
s to be compared with Book
s.
A comparison like the one above, which ignores some fields of the struct,
can be dangerous. It can easily lead to an unintended violation of the
requirements for a partial equivalence relation. For example, if we kept
the above implementation of PartialEq<Book>
for BookFormat
and added an
implementation of PartialEq<Book>
for Book
(either via a #[derive]
or
via the manual implementation from the first example) then the result would
violate transitivity:
#[derive(PartialEq)] enum BookFormat { Paperback, Hardback, Ebook, } #[derive(PartialEq)] struct Book { isbn: i32, format: BookFormat, } impl PartialEq<BookFormat> for Book { fn eq(&self, other: &BookFormat) -> bool { self.format == *other } } impl PartialEq<Book> for BookFormat { fn eq(&self, other: &Book) -> bool { *self == other.format } } fn main() { let b1 = Book { isbn: 1, format: BookFormat::Paperback }; let b2 = Book { isbn: 2, format: BookFormat::Paperback }; assert!(b1 == BookFormat::Paperback); assert!(BookFormat::Paperback == b2); // The following should hold by transitivity but doesn't. assert!(b1 == b2); // <-- PANICS }
Examples
let x: u32 = 0; let y: u32 = 1; assert_eq!(x == y, false); assert_eq!(x.eq(&y), false);
Required methods
Provided methods
Implementations on Foreign Types
impl<A, B, C, D, E, F, G, H, I, J, K, L> PartialEq<(A, B, C, D, E, F, G, H, I, J, K, L)> for (A, B, C, D, E, F, G, H, I, J, K, L) where
C: PartialEq<C>,
K: PartialEq<K>,
A: PartialEq<A>,
F: PartialEq<F>,
E: PartialEq<E>,
D: PartialEq<D>,
I: PartialEq<I>,
B: PartialEq<B>,
G: PartialEq<G>,
H: PartialEq<H>,
J: PartialEq<J>,
L: PartialEq<L> + ?Sized,
[src]
impl<A, B, C, D, E, F, G, H, I, J, K, L> PartialEq<(A, B, C, D, E, F, G, H, I, J, K, L)> for (A, B, C, D, E, F, G, H, I, J, K, L) where
C: PartialEq<C>,
K: PartialEq<K>,
A: PartialEq<A>,
F: PartialEq<F>,
E: PartialEq<E>,
D: PartialEq<D>,
I: PartialEq<I>,
B: PartialEq<B>,
G: PartialEq<G>,
H: PartialEq<H>,
J: PartialEq<J>,
L: PartialEq<L> + ?Sized,
[src]impl<A, B, C, D, E, F, G, H, I, J, K> PartialEq<(A, B, C, D, E, F, G, H, I, J, K)> for (A, B, C, D, E, F, G, H, I, J, K) where
C: PartialEq<C>,
K: PartialEq<K> + ?Sized,
A: PartialEq<A>,
F: PartialEq<F>,
E: PartialEq<E>,
D: PartialEq<D>,
I: PartialEq<I>,
B: PartialEq<B>,
G: PartialEq<G>,
H: PartialEq<H>,
J: PartialEq<J>,
[src]
impl<A, B, C, D, E, F, G, H, I, J, K> PartialEq<(A, B, C, D, E, F, G, H, I, J, K)> for (A, B, C, D, E, F, G, H, I, J, K) where
C: PartialEq<C>,
K: PartialEq<K> + ?Sized,
A: PartialEq<A>,
F: PartialEq<F>,
E: PartialEq<E>,
D: PartialEq<D>,
I: PartialEq<I>,
B: PartialEq<B>,
G: PartialEq<G>,
H: PartialEq<H>,
J: PartialEq<J>,
[src]impl<A, B, C, D, E, F, G, H, I, J> PartialEq<(A, B, C, D, E, F, G, H, I, J)> for (A, B, C, D, E, F, G, H, I, J) where
C: PartialEq<C>,
A: PartialEq<A>,
F: PartialEq<F>,
E: PartialEq<E>,
D: PartialEq<D>,
I: PartialEq<I>,
B: PartialEq<B>,
G: PartialEq<G>,
H: PartialEq<H>,
J: PartialEq<J> + ?Sized,
[src]
impl<A, B, C, D, E, F, G, H, I, J> PartialEq<(A, B, C, D, E, F, G, H, I, J)> for (A, B, C, D, E, F, G, H, I, J) where
C: PartialEq<C>,
A: PartialEq<A>,
F: PartialEq<F>,
E: PartialEq<E>,
D: PartialEq<D>,
I: PartialEq<I>,
B: PartialEq<B>,
G: PartialEq<G>,
H: PartialEq<H>,
J: PartialEq<J> + ?Sized,
[src]impl<T, S1, S2> PartialEq<IndexSet<T, S2>> for IndexSet<T, S1> where
T: Hash + Eq,
S1: BuildHasher,
S2: BuildHasher,
[src]
impl<T, S1, S2> PartialEq<IndexSet<T, S2>> for IndexSet<T, S1> where
T: Hash + Eq,
S1: BuildHasher,
S2: BuildHasher,
[src]impl<K, V1, S1, V2, S2> PartialEq<IndexMap<K, V2, S2>> for IndexMap<K, V1, S1> where
K: Hash + Eq,
S1: BuildHasher,
S2: BuildHasher,
V1: PartialEq<V2>,
[src]
impl<K, V1, S1, V2, S2> PartialEq<IndexMap<K, V2, S2>> for IndexMap<K, V1, S1> where
K: Hash + Eq,
S1: BuildHasher,
S2: BuildHasher,
V1: PartialEq<V2>,
[src]impl<T, S> PartialEq<HashSet<T, S>> for HashSet<T, S> where
T: Eq + Hash,
S: BuildHasher,
impl<T, S> PartialEq<HashSet<T, S>> for HashSet<T, S> where
T: Eq + Hash,
S: BuildHasher,
impl PartialEq<TryReserveError> for TryReserveError
impl PartialEq<TryReserveError> for TryReserveError
impl<K, V, S> PartialEq<HashMap<K, V, S>> for HashMap<K, V, S> where
K: Eq + Hash,
V: PartialEq<V>,
S: BuildHasher,
impl<K, V, S> PartialEq<HashMap<K, V, S>> for HashMap<K, V, S> where
K: Eq + Hash,
V: PartialEq<V>,
S: BuildHasher,
impl<T, U> PartialEq<Rc<U>> for ArchivedRc<T> where
T: ArchivePointee + PartialEq<U> + ?Sized,
U: ?Sized,
[src]
impl<T, U> PartialEq<Rc<U>> for ArchivedRc<T> where
T: ArchivePointee + PartialEq<U> + ?Sized,
U: ?Sized,
[src]impl<T, U> PartialEq<Arc<U>> for ArchivedArc<T> where
T: ArchivePointee + PartialEq<U> + ?Sized,
U: ?Sized,
[src]
impl<T, U> PartialEq<Arc<U>> for ArchivedArc<T> where
T: ArchivePointee + PartialEq<U> + ?Sized,
U: ?Sized,
[src]impl<K, V> PartialEq<ArchivedHashMap<K, V>> for ArchivedHashMap<K, V> where
K: Hash + Eq,
V: PartialEq<V>,
[src]
impl<K, V> PartialEq<ArchivedHashMap<K, V>> for ArchivedHashMap<K, V> where
K: Hash + Eq,
V: PartialEq<V>,
[src]impl<T, U> PartialEq<Box<U, Global>> for ArchivedBox<T> where
T: ArchivePointee + PartialEq<U> + ?Sized,
U: ?Sized,
[src]
impl<T, U> PartialEq<Box<U, Global>> for ArchivedBox<T> where
T: ArchivePointee + PartialEq<U> + ?Sized,
U: ?Sized,
[src]impl<K> PartialEq<ArchivedHashSet<K>> for ArchivedHashSet<K> where
K: PartialEq<K> + Hash + Eq,
[src]
impl<K> PartialEq<ArchivedHashSet<K>> for ArchivedHashSet<K> where
K: PartialEq<K> + Hash + Eq,
[src]impl<T> PartialEq<ArchivedRangeInclusive<T>> for ArchivedRangeInclusive<T> where
T: PartialEq<T>,
[src]
impl<T> PartialEq<ArchivedRangeInclusive<T>> for ArchivedRangeInclusive<T> where
T: PartialEq<T>,
[src]Implementors
impl<B, C> PartialEq<ControlFlow<B, C>> for ControlFlow<B, C> where
C: PartialEq<C>,
B: PartialEq<B>,
1.55.0[src]
impl<B, C> PartialEq<ControlFlow<B, C>> for ControlFlow<B, C> where
C: PartialEq<C>,
B: PartialEq<B>,
1.55.0[src]impl<Dyn> PartialEq<DynMetadata<Dyn>> for wasmer_types::lib::std::ptr::DynMetadata<Dyn> where
Dyn: ?Sized,
[src]
impl<Dyn> PartialEq<DynMetadata<Dyn>> for wasmer_types::lib::std::ptr::DynMetadata<Dyn> where
Dyn: ?Sized,
[src]impl<Idx> PartialEq<RangeInclusive<Idx>> for RangeInclusive<Idx> where
Idx: PartialEq<Idx>,
1.26.0[src]
impl<Idx> PartialEq<RangeInclusive<Idx>> for RangeInclusive<Idx> where
Idx: PartialEq<Idx>,
1.26.0[src]impl<Idx> PartialEq<RangeToInclusive<Idx>> for RangeToInclusive<Idx> where
Idx: PartialEq<Idx>,
1.26.0[src]
impl<Idx> PartialEq<RangeToInclusive<Idx>> for RangeToInclusive<Idx> where
Idx: PartialEq<Idx>,
1.26.0[src]impl<K, V> PartialEq<SecondaryMap<K, V>> for SecondaryMap<K, V> where
K: EntityRef,
V: Clone + PartialEq,
[src]
impl<K, V> PartialEq<SecondaryMap<K, V>> for SecondaryMap<K, V> where
K: EntityRef,
V: Clone + PartialEq,
[src]impl<K: PartialEq, V: PartialEq> PartialEq<PrimaryMap<K, V>> for PrimaryMap<K, V> where
K: EntityRef,
[src]
impl<K: PartialEq, V: PartialEq> PartialEq<PrimaryMap<K, V>> for PrimaryMap<K, V> where
K: EntityRef,
[src]Equality for two Rc
s.
Two Rc
s are equal if their inner values are equal, even if they are
stored in different allocation.
If T
also implements Eq
(implying reflexivity of equality),
two Rc
s that point to the same allocation are
always equal.
Examples
use std::rc::Rc; let five = Rc::new(5); assert!(five == Rc::new(5));
Inequality for two Rc
s.
Two Rc
s are unequal if their inner values are unequal.
If T
also implements Eq
(implying reflexivity of equality),
two Rc
s that point to the same allocation are
never unequal.
Examples
use std::rc::Rc; let five = Rc::new(5); assert!(five != Rc::new(6));
Equality for two Arc
s.
Two Arc
s are equal if their inner values are equal, even if they are
stored in different allocation.
If T
also implements Eq
(implying reflexivity of equality),
two Arc
s that point to the same allocation are always equal.
Examples
use std::sync::Arc; let five = Arc::new(5); assert!(five == Arc::new(5));
Inequality for two Arc
s.
Two Arc
s are unequal if their inner values are unequal.
If T
also implements Eq
(implying reflexivity of equality),
two Arc
s that point to the same value are never unequal.
Examples
use std::sync::Arc; let five = Arc::new(5); assert!(five != Arc::new(6));
impl<Y, R> PartialEq<GeneratorState<Y, R>> for GeneratorState<Y, R> where
R: PartialEq<R>,
Y: PartialEq<Y>,
[src]
impl<Y, R> PartialEq<GeneratorState<Y, R>> for GeneratorState<Y, R> where
R: PartialEq<R>,
Y: PartialEq<Y>,
[src]