Rust 语言从入门到实战
唐刚
Rust 语言中文社区联合创始人
5266 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 36 讲
Rust 语言从入门到实战
15
15
1.0x
00:00/00:00
登录|注册

09|初识trait:协议约束与能力配置

你好,我是 Mike。今天我们来一起学习 trait。
trait 在 Rust 中非常重要。如果说所有权是 Rust 中的九阳神功(内功护体),那么类型系统(types + trait)就是 Rust 中的降龙十八掌,学好了便如摧枯拉朽般解决问题。另外一方面,如果把 Rust 比作一个 AI 人的话,那么所有权相当于 Rust 的心脏,类型 + trait 相当于这个 AI 人的大脑。
好了,我就不卖关子了。前面我们已经学习了所有权,现在我们来了解一下这个 trait 到底是什么。
注:所有权是这门课程的主线,会一直贯穿到最后。

trait 是什么?

trait 用中文来讲就是特征,但是我倾向于不翻译。因为 trait 本身很简单,它就是一个标记(marker 或 tag)而已。比如 trait TraitA {} 就定义了一个 trait,TraitA。
只不过这个标记被用在特定的地方,也就是类型参数的后面,用来限定(bound)这个类型参数可能的类型范围。所以 trait 往往是跟类型参数结合起来使用的。比如 T: TraitA 就是使用 TraitA 对类型参数 T 进行限制。
这么讲起来比较抽象,我们下面举例说明。

trait 是一种约束

我们先回忆一下第 7 讲的一个例子。
struct Point<T> {
x: T,
y: T,
}
fn print<T: std::fmt::Display>(p: Point<T>) {
println!("Point {}, {}", p.x, p.y);
}
fn main() {
let p = Point {x: 10, y: 20};
print(p);
let p = Point {x: 10.2, y: 20.4};
print(p);
}
// 输出
Point 10, 20
Point 10.2, 20.4
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Rust中的trait是一种强大的特性,通过约束和能力配置来限定类型参数的类型范围,并为具体类型提供能力。本文通过示例代码展示了trait的约束作用,以及如何为具体类型提供能力。同时,还介绍了如何实现trait以及多trait组合的约束表达式。Trait作为一种协议,强制不同成员之间达成一致,适合团队开发。文章还介绍了Where语法来解决过多的trait约束问题。另外,还讨论了约束依赖、约束中同名方法的访问、用trait实现能力配置、约束可按需配置以及孤儿规则等内容。总的来说,trait在Rust中扮演着重要的角色,对类型参数进行约束的同时,也为具体类型提供了能力,使得代码更加灵活和优雅。Trait的引入是为了对泛型的类型空间进行约束,进入约束的同时也就提供了能力,约束与能力是一体两面。文章还强调了Rust是一门面向约束编程的语言,这是Rust的独特设计和灵魂。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Rust 语言从入门到实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(24)

  • 最新
  • 精选
  • Mike Tang
    置顶
    神说,众生平等。Rust说,众trait平等。
    2023-11-09归属地:重庆
    1
    7
  • 下雨天
    trait 的依赖:小明要听从数学老师,语文老师,英语老师的话。老师之间是平等关系,多个依赖平等,最小依赖选择自己喜欢滴功能。 OOP 继承:小明要听他爸,他爷爷,他曾祖父的话。继承之间存在父子关系,继承过来一堆破属性和方法,也许根本不是自己想要滴,还要负重前行。

    作者回复: 太形象了,10000个赞

    2023-11-08归属地:湖北
    3
    21
  • weineel
    在语法层面实践了组合优于继承。

    作者回复: 对的对的.

    2024-01-01归属地:江苏
    3
  • superggn
    笔记 一般我们说关联类型 / associated types 的时候, 说的是 trait 底下的 type 关联类型就是跟着 trait 走的泛型 至于啥时候关联类型要具化 / 单态化 / 具体写明白是啥? 得在 impl trait for typeA 的时候写清楚 一般说 A 有 trait bound, 意思就是这个 A 必须实现某个 trait 我们不仅可以搞 trait bound, 有 trait bound 之后在 where clause 里还可以搞 trait type bound: `T: trait A, T::typeB: Debug + PartialEq` 为啥调用 trait 方法还需要 use trait? 因为 rust 不会大海捞针遍历所有 trait 找方法, 你得先指定在哪儿找

    作者回复: 非常🎉棒

    2023-12-15归属地:北京
    1
  • $侯
    既然关联类型作为占位符,那为什么这样会报错呢,按我理解理占位符应该不需要事先声明 pub trait Sport { type SportType; fn play(&self, st: SportType); } fn main() {} error[E0412]: cannot find type `SportType` in this scope --> src\main.rs:4:24 | 4 | fn play(&self, st: SportType); | ^^^^^^^^^ help: you might have meant to use the associated type: `Self::SportType`

    作者回复: 他提示了,用 Self::SportType,完整路径。我发现我那个例子也漏了,我加上。

    2023-11-17归属地:浙江
    1
  • cluski
    个人理解,trait很像Java中的interface。Java的interface可以作为某种能力的抽象,并且在泛型的使用中,可以起到限制的作用。 Java、C++等OOP语言中的继承个人感觉更多是在强调is-a这个概念。例如,男人是一个人,鸽子是一个鸟这类。与Rust的trait更加强调的一种能力和约束。

    作者回复: 对的。rust的trait将模型从oop的等级森严的牢房里面解救出来了

    2023-11-08归属地:江苏
    1
  • 啊良梓是我
    有没有入门项目来练练手, 看完就忘了,不上手的话

    作者回复: 后面实战篇就是几个入门的项目

    2024-03-06归属地:广东
  • 飞了的鸭子被煮了
    trait 不需要考虑层级关系,感觉类型的约束更加原子化了,被消费时不需要考虑那么多的耦合。

    作者回复: 👍👍

    2024-01-22归属地:湖南
  • 千回百转无劫山
    从python过来的,只能说打开了新世界的大门

    作者回复: rust不给开发者设置天花板

    2023-12-27归属地:北京
  • superggn
    思考题(我从 python 来的, cpp 和 java 没学过) OOP class 里有各种方法, 搞个子类就可以对基类进行各种修改 定义个 class, class 里有各种方法(包括 static method 啥的) 大部分情况是一个树形结构 面向 trait bound 编程 trait 类似于 OOP 里搞一个标准基类, 然后来回继承, 不同点在于更灵活 或者类似于 python3 里的 mixin(这玩意我没怎么玩过, 不熟, 但看过同事写的代码), 搞个 must implement 的 abstract method 感觉也差不多 引用来引用去, 飞来飞去~ 这种思考题没啥感觉, 反正我也不会写, 随便叨叨, 等全都刷一遍之后可能会有别的感想

    作者回复: 最好不要通过继承那个思维来理解,对的,先刷完一遍再回头来看。

    2023-12-15归属地:北京
收起评论
显示
设置
留言
24
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部