En el lenguaje Rust, PartialEq y Eq son dos rasgos muy importantes. Se usan para comparar valores de tipos, PartialEq se usa para comparar igualdad parcial (no necesariamente igualdad exacta), y Eq se usa para comparar igualdad exacta.
En Rust, cualquier tipo puede implementar PartialEq y Eq, por lo que estos dos rasgos son muy flexibles.
Uso básico
comparar enteros
fn main() {
let a = 10;
let b = 20;
if a == b {
println!("a equals b");
} else {
println!("a does not equal b");
}
}
复制代码
producción:
a does not equal b
复制代码
comparar cadenas
fn main() {
let a = "hello";
let b = "world";
if a == b {
println!("a equals b");
} else {
println!("a does not equal b");
}
}
复制代码
producción:
a does not equal b
复制代码
Comparar tipos personalizados
#[derive(PartialEq, Eq)]
struct Person {
name: String,
age: u8,
}
fn main() {
let p1 = Person {
name: "Alice".to_string(),
age: 30,
};
let p2 = Person {
name: "Bob".to_string(),
age: 30,
};
if p1 == p2 {
println!("p1 equals p2");
} else {
println!("p1 does not equal p2");
}
}
复制代码
producción:
p1 does not equal p2
复制代码
Comparar números de punto flotante
fn main() {
let a = 0.1 + 0.2;
let b = 0.3;
if a == b {
println!("a equals b");
} else {
println!("a does not equal b");
}
}
复制代码
producción:
a does not equal b
复制代码
función de comparación personalizada
#[derive(PartialEq, Eq)]
struct Person {
name: String,
age: u8,
}
impl PartialEq for Person {
fn eq(&self, other: &Self) -> bool {
self.age == other.age
}
}
impl Eq for Person {}
fn main() {
let p1 = Person {
name: "Alice".to_string(),
age: 30,
};
let p2 = Person {
name: "Bob".to_string(),
age: 30,
};
if p1 == p2 {
println!("p1 equals p2");
} else {
println!("p1 does not equal p2");
}
}
复制代码
producción:
p1 equals p2
复制代码
Comparación de tipos enumerados
#[derive(PartialEq, Eq)]
enum Color {
Red,
Blue,
}
fn main() {
let c1 = Color::Red;
let c2 = Color::Blue;
if c1 == c2 {
println!("c1 equals c2");
} else {
println!("c1 does not equal c2");
}
}
复制代码
producción:
c1 does not equal c2
复制代码
Utilice la macro assert_eq!
fn main() {
let a = 10;
let b = 20;
assert_eq!(a, b);
}
复制代码
producción:
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `10`,
right: `20`', src/main.rs:4:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
复制代码
Utilice la macro assert_ne!
fn main() {
let a = 10;
let b = 20;
assert_ne!(a, b);
}
复制代码
producción:
thread 'main' panicked at 'assertion failed: `(left != right)`
left: `10`,
right: `10`', src/main.rs:4:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
复制代码
Uso avanzado
función de comparación personalizada
#[derive(PartialEq, Eq)]
struct Person {
name: String,
age: u8,
}
impl PartialEq for Person {
fn eq(&self, other: &Self) -> bool {
self.age == other.age
}
}
impl Eq for Person {}
fn main() {
let p1 = Person {
name: "Alice".to_string(),
age: 30,
};
let p2 = Person {
name: "Bob".to_string(),
age: 40,
};
if p1 == p2 {
println!("p1 equals p2");
} else {
println!("p1 does not equal p2");
}
}
复制代码
producción:
p1 does not equal p2
复制代码
usar genéricos
#[derive(PartialEq, Eq)]
struct Pair<T> {
first: T,
second: T,
}
fn main() {
let p1 = Pair {
first: 1,
second: 2,
};
let p2 = Pair {
first: 2,
second: 1,
};
if p1 == p2 {
println!("p1 equals p2");
} else {
println!("p1 does not equal p2");
}
}
复制代码
producción:
p1 does not equal p2
复制代码
Usando PartialOrd y Ord
#[derive(PartialEq, Eq, PartialOrd, Ord)]
struct Person {
name: String,
age: u8,
}
fn main() {
let p1 = Person {
name: "Alice".to_string(),
age: 30,
};
let p2 = Person {
name: "Bob".to_string(),
age: 40,
};
if p1 < p2 {
println!("p1 is younger than p2");
} else {
println!("p1 is older than or equal to p2");
}
}
复制代码
producción:
p1 is younger than p2
复制代码
Uso de depuración y visualización
#[derive(Debug, PartialEq, Eq)]
struct Person {
name: String,
age: u8,
}
use std::fmt;
impl fmt::Display for Person {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} ({})", self.name, self.age)
}
}
fn main() {
let p1 = Person {
name: "Alice".to_string(),
age: 30,
};
let p2 = Person {
name: "Bob".to_string(),
age: 40,
};
println!("p1: {}", p1);
println!("p2: {}", p2);
}
复制代码
producción:
p1: Alice (30)
p2: Bob (40)
复制代码
Mejores prácticas
Al implementar PartialEq y Eq, se deben considerar los siguientes puntos:
- Para los tipos personalizados, se deben comparar todas las variables miembro, no solo algunas.
- Para números de coma flotante, se deben usar comparaciones aproximadas en lugar de comparaciones exactas.
- Para los tipos de enumeración, se deben comparar todas las variables miembro, no solo el valor de la enumeración en sí.
- Si el tipo a comparar implementa PartialOrd y Ord, estos dos rasgos deben usarse primero.
en conclusión
En el lenguaje Rust, PartialEq y Eq son rasgos muy importantes para comparar valores de tipos. Estos dos rasgos son tan flexibles que cualquier tipo puede implementarlos. Al implementar PartialEq y Eq, debe considerar las características del tipo, comparar todas las variables miembro, usar una comparación aproximada, etc.