rust派生特性

举报
yd_254179665 发表于 2025/07/28 14:52:37 2025/07/28
【摘要】 Rust 是一种系统级编程语言,以其内存安全和并发性而闻名。Rust 提供了多种派生特性(derive attributes),可以自动为结构体、枚举等类型实现某些特性。这些特性使得编写代码更加方便和高效。PartialEq 和 Eq定义:PartialEq 和 Eq 特性用于实现相等比较。用途:PartialEq 用于实现部分相等比较,Eq 用于实现完全相等比较。实现:Rust 编译器会自...

Rust 是一种系统级编程语言,以其内存安全和并发性而闻名。Rust 提供了多种派生特性(derive attributes),可以自动为结构体、枚举等类型实现某些特性。这些特性使得编写代码更加方便和高效。

PartialEq  Eq
  • 定义PartialEq  Eq 特性用于实现相等比较。
  • 用途PartialEq 用于实现部分相等比较,Eq 用于实现完全相等比较。
  • 实现:Rust 编译器会自动生成 PartialEq  Eq 的实现,根据结构体的字段生成相应的比较逻辑。
#[derive(PartialEq, Eq)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 1, y: 2 };
    let p3 = Point { x: 2, y: 3 };

    println!("p1 == p2: {}", p1 == p2); // 输出: p1 == p2: true
    println!("p1 == p3: {}", p1 == p3); // 输出: p1 == p3: false
}

可以通过实现 PartialEq 特性来自定义相等比较逻辑。例如,对于一个包含浮点数的结构体,可以自定义 PartialEq 实现,处理 NaN 的情况。

#[derive(Debug)]
struct Point {
    x: f64,
    y: f64,
}

impl PartialEq for Point {
    fn eq(&self, other: &Self) -> bool {
        self.x == other.x && self.y == other.y
    }
}

fn main() {
    let p1 = Point { x: 1.0, y: 2.0 };
    let p2 = Point { x: 1.0, y: 2.0 };
    let p3 = Point { x: f64::NAN, y: 2.0 };

    println!("p1 == p2: {}", p1 == p2); // 输出: p1 == p2: true
    println!("p1 == p3: {}", p1 == p3); // 输出: p1 == p3: false
    println!("p3 == p3: {}", p3 == p3); // 输出: p3 == p3: false
}
PartialOrd  Ord
  • 定义PartialOrd  Ord 特性用于实现部分和完全有序比较。
  • 用途PartialOrd 用于实现部分有序比较,Ord 用于实现完全有序比较。
  • 实现:Rust 编译器会自动生成 PartialOrd  Ord 的实现,根据结构体的字段生成相应的比较逻辑。
#[derive(PartialOrd, Ord)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 1, y: 2 };
    let p3 = Point { x: 2, y: 3 };

    println!("p1 <= p2: {}", p1 <= p2); // 输出: p1 <= p2: true
    println!("p1 < p3: {}", p1 < p3);   // 输出: p1 < p3: true
}
PartialOrd 的自定义实现
需要实现 PartialOrd 特性中的 partial_cmp 方法。partial_cmp 方法返回一个 Option<Ordering>,其中 Ordering 是一个枚举类型,表示两个值之间的关系(LessEqualGreater)。
use std::cmp::Ordering;

#[derive(Debug)]
struct Point {
    x: f64,
    y: f64,
}

impl PartialOrd for Point {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        // 首先比较 x 值
        match self.x.partial_cmp(&other.x) {
            Some(Ordering::Equal) => {
                // 如果 x 值相等,再比较 y 值
                self.y.partial_cmp(&other.y)
            }
            other => other,
        }
    }
}

fn main() {
    let p1 = Point { x: 1.0, y: 2.0 };
    let p2 = Point { x: 1.0, y: 2.0 };
    let p3 = Point { x: 2.0, y: 3.0 };

    println!("p1 <= p2: {:?}", p1.partial_cmp(&p2)); // 输出: p1 <= p2: Some(Equal)
    println!("p1 < p3: {:?}", p1.partial_cmp(&p3));  // 输出: p1 < p3: Some(Less)
    println!("p3 > p1: {:?}", p3.partial_cmp(&p1));  // 输出: p3 > p1: Some(Greater)
}
Hash
  • 定义Hash 特性用于实现哈希计算。
  • 用途:当需要将结构体实例存储在哈希集合(如 HashSet)或哈希映射(如 HashMap)中时,需要实现 Hash 特性。
  • 实现:Rust 编译器会自动生成 Hash 的实现,根据结构体的字段生成相应的哈希值。
use std::collections::HashSet;

#[derive(Hash, Eq, PartialEq)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let mut set = HashSet::new();
    set.insert(Point { x: 1, y: 2 });
    set.insert(Point { x: 1, y: 2 });

    println!("Set contains 1, 2: {}", set.contains(&Point { x: 1, y: 2 })); // 输出: Set contains 1, 2: true
}
Default
  • 定义Default 特性用于实现默认值。
  • 用途:当需要为结构体实例提供默认值时,可以使用 Default 特性。
  • 实现:Rust 编译器会自动生成 Default 的实现,根据结构体的字段生成相应的默认值。
#[derive(Default)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p = Point::default();
    println!("Default Point: x = {}, y = {}", p.x, p.y); // 输出: Default Point: x = 0, y = 0
}
Serialize  Deserialize
  • 定义Serialize  Deserialize 特性用于实现序列化和反序列化。
  • 用途:当需要将结构体实例转换为字符串(如 JSON)或从字符串转换回结构体实例时,可以使用 Serialize  Deserialize 特性。
  • 实现:需要引入 serde  serde_derive 库。

在Cargo.toml文件中引入

[package]
name = "example"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0"
serde_json="1.0"

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p = Point { x: 1, y: 2 };
    let serialized = serde_json::to_string(&p).unwrap();
    println!("Serialized: {}", serialized); // 输出: Serialized: {"x":1,"y":2}

    let deserialized: Point = serde_json::from_str(&serialized).unwrap();
    println!("Deserialized: x = {}, y = {}", deserialized.x, deserialized.y); // 输出: Deserialized: x = 1, y = 2
}
Display
  • 定义Display 特性用于实现自定义的字符串表示。
  • 用途:当需要将结构体实例转换为字符串时,可以使用 Display 特性。
  • 实现:Rust 编译器会自动生成 Display 的实现,根据结构体的字段生成相应的字符串表示。

use std::fmt;

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

impl fmt::Display for Point {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.x, self.y)
    }
}

fn main() {
    let p = Point { x: 1, y: 2 };
    println!("Point: {}", p); // 输出: Point: (1, 2)
}

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。