0Pricing
Learn Rust Coding · 课时

默认方法

特征默认实现

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

带函数体的方法

特征方法不必只有签名。特征可以提供默认实现——实现者会自动获得的方法体。

这能减少许多类型中的样板代码。

默认方法

直接在特征中编写方法体。实现该特征的类型会免费继承它,无需额外代码。

trait Greet {
    fn hello(&self) -> String {
        String::from("Hello there")
    }
}

struct Robot;
impl Greet for Robot {}

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

覆盖默认实现

任何实现者都可以通过提供自己的版本来覆盖默认实现。对于该类型,覆盖版本会取代默认版本。

trait Greet {
    fn hello(&self) -> String { String::from("Hello there") }
}

struct Robot;
struct Pirate;
impl Greet for Robot {}
impl Greet for Pirate {
    fn hello(&self) -> String { String::from("Arr!") }
}

fn main() {
    println!("{}", Robot.hello());
    println!("{}", Pirate.hello());
}

默认实现调用必需方法

默认方法可以调用同一特征的其他方法,即使这些方法没有默认实现。这是一种强大的模式:实现者提供一个小型核心,默认实现则在其上构建更丰富的行为。

trait Summary {
    fn title(&self) -> String;
    fn preview(&self) -> String {
        format!("Read more about: {}", self.title())
    }
}

struct Article { headline: String }
impl Summary for Article {
    fn title(&self) -> String { self.headline.clone() }
}

fn main() {
    let a = Article { headline: String::from("Rust Rocks") };
    println!("{}", a.preview());
}

模板方法模式

这种必需方法加默认实现的组合称为模板方法模式。特征在默认实现中定义整体流程,并将可变部分留给必需方法。

trait Report {
    fn body(&self) -> String;
    fn render(&self) -> String {
        format!("=== REPORT ===\n{}\n==============", self.body())
    }
}

struct Sales;
impl Report for Sales {
    fn body(&self) -> String { String::from("Sales up 10%") }
}

fn main() {
    println!("{}", Sales.render());
}

多个默认实现

特征可以自由混合必需方法和默认方法。实现者只需提供必需的方法。

trait Animal {
    fn name(&self) -> String;
    fn legs(&self) -> u32 { 4 }
    fn describe(&self) -> String {
        format!("{} has {} legs", self.name(), self.legs())
    }
}

struct Dog;
impl Animal for Dog {
    fn name(&self) -> String { String::from("Dog") }
}

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

默认实现与标准特征

许多标准特征都依赖默认实现。例如,Iterator 只要求实现 next;每个适配器和使用者都是基于它构建的默认方法。

这就是为什么一个方法就能解锁整套工具的原因。

为提升性能而覆盖

有时默认实现可以正常工作,但专用版本会更快。实现者可以只覆盖该方法,同时保留其余默认实现。

trait Counter {
    fn items(&self) -> Vec<i32>;
    fn total(&self) -> i32 {
        self.items().iter().sum()
    }
}

struct Fast { precomputed: i32 }
impl Counter for Fast {
    fn items(&self) -> Vec<i32> { vec![] }
    fn total(&self) -> i32 { self.precomputed }
}

fn main() {
    println!("{}", Fast { precomputed: 99 }.total());
}

让特征易于使用

良好的特征设计是:只要求实现少量方法,并为其余方法提供方便的默认实现。实现者只需完成最少的工作,却能获得丰富的接口。

注意事项

默认方法只能使用其他特征方法,以及通过这些方法访问 self 背后的类型;它不能直接访问未知实现者的字段。请围绕特征自身的方法设计默认实现。

默认方法与必需方法一览

带方法体的特征方法是默认方法;只有签名的方法是必需方法。实现者必须提供每个必需方法,但可以不修改默认方法。

trait Logger {
    fn line(&self) -> String;
    fn log(&self) {
        println!("LOG: {}", self.line());
    }
}

struct App;
impl Logger for App {
    fn line(&self) -> String { String::from("started") }
}

fn main() {
    App.log();
}

快速检查

检验您对默认方法的理解。

回顾

您学习了特征的默认实现:

  • 特征方法可以包含方法体,作为默认实现
  • 实现者可以免费继承它,也可以覆盖它
  • 默认实现可以调用必需方法,从而实现模板方法模式
  • 只保留少量必需方法,就能让特征易于使用

常见问题解答

「默认方法」课时是免费的吗?

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

「默认方法」这节课中我会学到什么?

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

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

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

「默认方法」课时需要多长时间?

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

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

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

此课程中的所有课时

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