0Pricing
Learn Rust Coding · 课时

定义特征

共享行为

定义特征 是 CoddyKit 上的免费 Learn Rust Coding 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn Rust Coding 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn Rust Coding 课程共包含 4 节课。

什么是 Trait?

Trait定义共享行为,即一种类型可以实现的一组方法。它类似于其他语言中的接口。

Trait 让不同类型能够遵守同一份公共契约。

声明 Trait

使用trait关键字,后面跟方法签名。方法签名声明了实现者必须提供的内容。

trait Greet {
    fn hello(&self) -> String;
}

fn main() {
    println!("trait declared");
}

实现 Trait

使用impl TraitName for Type来提供这些方法。方法签名必须与 Trait 完全匹配。

trait Greet {
    fn hello(&self) -> String;
}

struct Dog;

impl Greet for Dog {
    fn hello(&self) -> String {
        String::from("Woof")
    }
}

fn main() {
    let d = Dog;
    println!("{}", d.hello());
}

多个类型,一个 Trait

多个类型可以实现同一个 Trait,并且各自采用不同的实现方式。这正是 Trait 能够统一不相关类型行为的原因。

trait Greet { fn hello(&self) -> String; }

struct Dog;
struct Cat;

impl Greet for Dog { fn hello(&self) -> String { String::from("Woof") } }
impl Greet for Cat { fn hello(&self) -> String { String::from("Meow") } }

fn main() {
    println!("{}", Dog.hello());
    println!("{}", Cat.hello());
}

将 Trait 作为函数参数

impl Trait语法接受任何实现了该 Trait 的类型。函数无需知道具体类型,就能以统一方式工作。

trait Greet { fn hello(&self) -> String; }
struct Dog;
impl Greet for Dog { fn hello(&self) -> String { String::from("Woof") } }

fn announce(g: &impl Greet) {
    println!("It says: {}", g.hello());
}

fn main() {
    announce(&Dog);
}

泛型的 Trait 约束

您可以使用Trait 约束要求泛型类型实现某个 Trait。这样就能在函数内部使用该 Trait 的方法。

trait Greet { fn hello(&self) -> String; }
struct Cat;
impl Greet for Cat { fn hello(&self) -> String { String::from("Meow") } }

fn shout<T: Greet>(g: &T) {
    println!("{}!", g.hello().to_uppercase());
}

fn main() {
    shout(&Cat);
}

使用 + 添加多个约束

使用+可以同时要求多个 Trait。这里,一个值必须同时实现自定义 Trait 和标准的Clone。

trait Named { fn name(&self) -> String; }

#[derive(Clone)]
struct Item { label: String }

impl Named for Item {
    fn name(&self) -> String { self.label.clone() }
}

fn describe<T: Named + Clone>(t: &T) {
    let copy = t.clone();
    println!("named {}", copy.name());
}

fn main() {
    describe(&Item { label: String::from("box") });
}

where 子句

当约束较多时,where子句会将这些限制移到签名下方,从而保持签名易读。

use std::fmt::Debug;

fn print_all<T>(items: &[T])
where
    T: Debug,
{
    for it in items {
        println!("{:?}", it);
    }
}

fn main() {
    print_all(&[1, 2, 3]);
}

Trait 可以包含多个方法

一个 Trait 可以声明多个方法。实现者必须提供所有必需的方法,从而为类型提供完整的行为集合。

trait Shape {
    fn area(&self) -> f64;
    fn name(&self) -> String;
}

struct Square { side: f64 }

impl Shape for Square {
    fn area(&self) -> f64 { self.side * self.side }
    fn name(&self) -> String { String::from("square") }
}

fn main() {
    let s = Square { side: 3.0 };
    println!("{} area {}", s.name(), s.area());
}

Trait 为什么重要

Trait 无需继承即可实现多态。它们支持泛型、运算符重载(Add)、格式化(Display)以及标准库中的许多功能。

Trait 是 Rust 抽象模型的核心。

一致性规则

孤儿规则规定:只有当您拥有该 Trait 或该类型时,才能为该类型实现该 Trait。这样可以防止不同包之间出现冲突的实现。

快速检查

测试您对 Trait 的理解。

回顾

您已经学会定义和使用 Trait:

  • trait声明共享行为
  • impl Trait for Type提供相应方法
  • Trait 约束(T: Trait、+、where)限制泛型
  • 孤儿规则确保实现保持一致

常见问题解答

「定义特征」课时是免费的吗?

是的 — 「定义特征」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn Rust Coding 课程的其余内容,请升级到 CoddyKit PRO。 Learn Rust Coding 课程共包含 4 节课。

「定义特征」这节课中我会学到什么?

共享行为 你通过在浏览器中直接运行的动手代码来练习 Learn Rust Coding,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Learn Rust Coding 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Learn Rust Coding 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「定义特征」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Learn Rust Coding 课中编写并运行代码吗?

能。每节 Learn Rust Coding 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 定义特征
  2. 特征对象与 dyn
  3. 静态分派与动态分派
  4. 默认方法
← 返回 Learn Rust Coding