
本节覆盖 Rust 标准库中最常用的一批 trait,并给出清晰的使用准则、典型示例与常见坑位修复建议。学完后你可在日常工程中熟练“派生、实现、组合”这些 trait,做出简洁高效的 API。
#[derive(Debug)]
struct User { id: u32, name: String }
// Display 需手写
use std::fmt::{self, Display, Formatter};
impl Display for User {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "User({}, {})", self.id, self.name)
}
}
fn main() {
let u = User { id: 1, name: "alice".into() };
println!("{:?}", u); // Debug
println!("{}", u); // Display
}
#[derive(Clone, Copy)]
struct Point { x: i32, y: i32 }
fn main() {
let p = Point { x: 1, y: 2 };
let q = p; // 触发 Copy 语义:按位复制,p 仍可使用
let r = p.clone(); // 调用 Clone 方法,同样复制数据
// 验证 p 仍可访问(Copy 语义的特点)
println!("p: ({}, {})", p.x, p.y);
println!("q: ({}, {})", q.x, q.y);
println!("r: ({}, {})", r.x, r.y);
}
Copy 仅限小且固定大小的类型;包含 String/Vec 等堆资源的类型不能 Copy。#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
struct Score { val: i32 }
fn main() {
let a = Score { val: 10 };
let b = Score { val: 20 };
assert!(a < b);
println!("{}",a < b);
}
PartialEq 支持 ==;Eq 表示自反性完全成立(如整数)。Ord 提供全序;常配合 #[derive(...)] 由字段顺序决定比较优先级。#[derive(Default)]
struct Config { retries: u32, verbose: bool }
fn main() { let c = Config::default(); }..Default::default() 可便捷构造:let c = Config { verbose: true, ..Default::default() };use std::convert::{From, TryFrom};
#[derive(Debug)]
struct Port(u16);
impl TryFrom<i32> for Port {
type Error = &'static str;
fn try_from(v: i32) -> Result<Self, Self::Error> {
if (0..=65535).contains(&v) {
Ok(Port(v as u16))
} else {
Err("out of range")
}
}
}
fn main() {
let p = Port::try_from(8080).unwrap();
// 修正:使用 to_string() 将 i32 转换为 String
let s: String = 42.to_string();
// 或使用 format! 宏:let s = format!("{}", 42);
println!("{:?} {}", p, s);
}
From<T> for U 后,自动获得 Into<U> for T。use std::ops::{Deref, DerefMut};
struct MyBox<T>(T);
impl<T> Deref for MyBox<T> { type Target = T; fn deref(&self) -> &T { &self.0 } }
impl<T> DerefMut for MyBox<T> { fn deref_mut(&mut self) -> &mut T { &mut self.0 } }
fn hello(s: &str) { println!("{}", s); }
fn main() {
let b = MyBox(String::from("world"));
hello(&b); // Deref 自动把 &MyBox<String> 转为 &String 再到 &str
}
Borrow<T>:面向集合键类型相等的借用视图(如 String 的键以 &str 查找)。AsRef<T>:廉价转换/借用视图,适合通用 API。fn read_all<P: AsRef<std::path::Path>>(p: P) -> std::io::Result<String> {
std::fs::read_to_string(p)
}use std::ops::Add;
#[derive(Debug, Clone, Copy)]
struct Vec2 { x: f64, y: f64 }
impl Add for Vec2 { type Output = Vec2; fn add(self, rhs: Vec2) -> Vec2 { Vec2 { x: self.x + rhs.x, y: self.y + rhs.y } } }use std::ops::{Index, IndexMut};
struct Bag(Vec<i32>);
impl Index<usize> for Bag { type Output = i32; fn index(&self, i: usize) -> &Self::Output { &self.0[i] } }
impl IndexMut<usize> for Bag { fn index_mut(&mut self, i: usize) -> &mut Self::Output { &mut self.0[i] } }struct Guard;
impl Drop for Guard { fn drop(&mut self) { println!("cleanup"); } }drop 里 panic。let sum: i32 = (1..=10).map(|x| x * 2).filter(|x| x % 3 == 0).sum();Iterator 的 next 方法。Fn:不可变捕获环境;FnMut:可变捕获;FnOnce:消耗捕获。fn call_twice<F: FnMut()>(mut f: F) { f(); f(); }struct New(T); 再实现;Copy 导致隐式复制引入逻辑错误 → 只在纯值类型上 Copy;Deref 过度重载引起奇怪隐式转换 → 保持克制;Display 未实现导致用户输出不友好 → 调试内部用 Debug,对外一定提供 Display;TryFrom/TryInto 的错误类型 → 指定 type Error 并返回 Result;Drop 中 panic! 造成双重崩溃 → 避免在析构中抛错。Vec2 完成 Sub、Mul(标量)、Display、From<(f64,f64)> 等实现;Config,用 Default + FromStr 支持环境变量或文件读取;LogLevel,实现 Display + FromStr + Ord 并写排序演示;Bag 实现 IntoIterator,支持 for x in &bag 与 for x in bag 两种遍历;TryFrom<&str> 实现端口/地址安全解析,并附带错误类型。小结:掌握常用 trait 的“何时派生、何时手写、何时约束”,能显著提升 API 的易用性与代码整洁度。下一节将继续补充错误处理与 Result/thiserror/anyhow 的组合拳实战。