本页目录

struct 与 trait

struct 有三种(具名字段/元组/单元),trait 是 Rust 对"接口"的回答——定义一组方法签名,任何类型可以实现它。derive 宏自动为 struct 生成常见 trait(Clone/Debug/Serialize),orphan rule 限制了"你能为谁实现谁的 trait",防止依赖冲突。

struct: 不仅仅是"数据的集合"

struct Point { x: f64, y: f64 }      // named fields — 最常见的
struct Color(u8, u8, u8);            // tuple struct — 匿名字段, 适用简单包装
struct AlwaysEqual;                   // unit struct — ZST, 用作 marker 类型

tuple struct 适合"新类型包装"——用一个单字段 struct 包装底层类型,赋予新的类型语义,防止误用:

struct Meters(f64);                  // 不是 f64 — 是 Meters!
struct Feet(f64);

let m = Meters(100.0);
let f = Feet(328.0);
// let sum = m.0 + f.0;              // 可以这么做, 但语义上不应该直接比较
// 编译器不会阻止你, 但类型系统帮你区分"这是米"和"那是英尺"

trait: 行为的契约

trait 定义了"一组方法签名"——任何实现该 trait 的类型都必须提供这些方法:

trait Summary {
    fn summarize(&self) -> String;    // 必须实现 (no default)
    
    fn default_summary(&self) -> String {  // 有默认实现, 可选 override
        String::from("(Read more...)")
    }
}

impl Summary for Point {
    fn summarize(&self) -> String {
        format!("Point({}, {})", self.x, self.y)
    }
}

trait 与 Java/C# 的 interface 类似,但一个重要区别:⁠你可以为外部类型实现自己的 trait(但不能为外部类型实现外部 trait——孤规则)。

Derive: 编译器自动生成代码

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

derive 要求所有字段也实现了对应 trait。例如 #[derive(Clone)] 要求每个字段是 Clone。编译器检查这些约束,然后生成模板化的 impl——不需要宏或代码生成工具。

Orphan Rule (孤规则): 为什么不能随便 impl

// 你的 crate: my_lib
impl Display for MyType { ... }      // OK: MyType 是你的
impl MyTrait for String { ... }      // OK: MyTrait 是你的
impl Display for Vec<MyType> { ... } // OK: Vec 的参数 MyType 是你的

// impl Display for String { ... }   // ERROR: Display(std) + String(std)
//     两个都在其他 crate 中定义 → orphan rule 禁止

这条规则防止了两个 crate 同时为同一个 (type, trait) 组合提供冲突的 impl——如果发生,编译器不知道选哪个,链接阶段的 coherence 检查会报错。这是 Rust trait 系统模块化的核心保证。

Trait Bounds: 约束泛型

// 单个 bound — 语法糖
fn notify(item: &impl Summary) { }

// 等价泛型写法
fn notify<T: Summary>(item: &T) { }

// 多个 bounds
fn notify<T: Summary + Display>(item: &T) { }

// where clause — 复杂 bounds 更可读
fn complex<T, U>(t: &T, u: &U) -> T::Output
where
    T: Display + Clone,
    U: Clone + Debug,
    T: Add<U>,
{ ... }

参考

  • Rust Book: Chapter 5 (struct), Chapter 10.2 (trait)
  • Rust Reference: Traits, orphan rules, derive

Keywords: struct, trait, impl, derive, orphan rule, coherence, trait bound, where clause