「Rust笔记」Rust之derive特性总结

「Rust笔记」Rust之derive特性总结

首页游戏大全Rust Red更新时间:2024-06-03
前言

编译器可以通过#[derive]为一些trait提供基础的实现。 如果需要更复杂的逻辑,这些trait也可以被手动实现。

这些可导入的实现:

Debug 用于程序员输出

Debug trait 用于开启格式化字符串中的调试格式,其通过在 {} 占位符中增加 :? 表明。

Debug trait 允许以调试目的来打印一个类型的实例,所以使用该类型的程序员可以在程序执行的特定时间点观察其实例。

例如,在使用 assert_eq! 宏时,Debug trait 是必须的。如果等式断言失败,这个宏就把给定实例的值作为参数打印出来,如此程序员可以看到两个实例为什么不相等。

#[derive(Debug)] struct ImportantExcerpt<'a>{ part: &'a str, } fn main() { let novel = String::from("Call me Ishmael. Some years ago..."); let first_sentence = novel.split('.').next().expect("Could not find a '.'"); let i = ImportantExcerpt { part: first_sentence }; println!("{:?}",i); }等值比较的 PartialEq 和 Eq

PartialEq trait 可以比较一个类型的实例以检查是否相等,并开启了 == 和 != 运算符的功能。

派生的 PartialEq 实现了 eq 方法。当 PartialEq 在结构体上派生时,只有所有 的字段都相等时两个实例才相等,同时只要有任何字段不相等则两个实例就不相等。当在枚举上派生时,每一个成员都和其自身相等,且和其他成员都不相等。

例如,当使用 assert_eq! 宏时,需要比较比较一个类型的两个实例是否相等,则 PartialEq trait 是必须的。

#[derive(Debug, Clone, Copy, Ord, Eq, PartialOrd, PartialEq, Hash)] enum Endpoint { OauthToken, Disciplines, PublicTournaments, MyTournaments, Matches, } lazy_static! { static ref API_EP: HashMap<Endpoint, &'static str> = { let mut m: HashMap<Endpoint, &'static str> = HashMap::new(); m.insert(Endpoint::OauthToken,"/oauth/v2/token"); m.insert(Endpoint::Disciplines,"/v1/disciplines"); m.insert(Endpoint::PublicTournaments,"/v1/tournaments"); m.insert(Endpoint::MyTournaments,"/v1/me/tournaments"); m.insert(Endpoint::Matches,"/v1/tournaments/{}/matches"); m }; }次序比较的 PartialOrd 和 Ord

PartialOrd trait 可以基于排序的目的而比较一个类型的实例。实现了 PartialOrd 的类型可以使用 <、 >、<= 和 >= 操作符。但只能在同时实现了 PartialEq 的类型上使用 PartialOrd。

use std::cmp::Ordering; #[derive(Eq)] struct Person { id: u32, name: String, height: u32, } impl PartialOrd for Person { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) } } impl Ord for Person { fn cmp(&self, other: &Self) -> Ordering { self.height.cmp(&other.height) } } impl PartialEq for Person { fn eq(&self, other: &Self) -> bool { self.height == other.height } }复制值的 Clone 和 Copy

Clone trait 可以明确地创建一个值的深拷贝(deep copy),复制过程可能包含任意代码的执行以及堆上数据的复制。查阅第四章 “变量和数据的交互方式:移动” 以获取有关 Clone 的更多信息。

#[derive(Clone)] struct Morpheus { blue_pill: f32, red_pill: i64, } fn main() { let f = Morpheus { blue_pill: 0.0, red_pill: 0 }; let copy = f.clone(); // and now we can clone it! }固定大小的值到值映射的 Hash

Hash trait 可以实例化一个任意大小的类型,并且能够用哈希(hash)函数将该实例映射到一个固定大小的值上。派生 Hash 实现了 hash 方法。hash 方法的派生实现结合了在类型的每部分调用 hash 的结果,这意味着所有的字段或值也必须实现了 Hash,这样才能够派生 Hash。

例如,在 HashMap<K, V> 上存储数据,存放 key 的时候,Hash 是必须的。

use std::collections::HashMap; #[derive(Debug, Hash)] struct Man{ pub age: i32, pub name: String, } impl PartialEq for Man{ fn eq(&self, other: &Self) -> bool { (self.age == other.age) && (self.name == other.name) } } impl Eq for Man{} fn test_1(){ let x1 = Man{ age: 11, name: String::from("tim"), }; let x2 = Man{ age: 12, name: String::from("sam"), }; let x3 = Man{ age: 11, name: String::from("tim"), }; let mut ahash = HashMap::new(); ahash.insert(&x1, 1i32); } fn main() { test_1(); } 默认值的 Default

Default trait 使你创建一个类型的默认值。 派生 Default 实现了 default 函数。default 函数的派生实现调用了类型每部分的 default 函数,这意味着类型中所有的字段或值也必须实现了 Default,这样才能够派生 Default 。

#[derive(Default,Debug)] //(Debug是为了方便打印) struct MyTest{ i:i32, j:Option<i32>, k:String, } fn main(){ let mt = MyTest::default(); println!("{:?}",mt); }

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved