Traits: Rust 中的统一概念
Rust 的traits来自 Haskell 的type classes,它是下边这些的概念的统一:
-
Interfaces
接口
-
Abstract classes
抽象类
-
Mix-ins
混入
-
Operator overloading
运算符重载
-
Constraints on generics / Concepts
对泛型/概念的限制 -
Behavioral markers / Attributes
行为标记/属性 -
(bonus) Method overloading
(奖励)方法重载
这真得很神奇!
我使用过的所有其他语言 [1] 都有上面列表的一些子集。我不认为他们中的任何一个都拥有所有这些,并且它们是具有自己的关键字和语法的不同概念。坦率地说,能够将所有这些统一起来真是太棒了。
Rust 没有特殊的接口语法,因为trait涵盖了这一点。 Rust 没有用于运算符重载的特殊语法,因为trait涵盖了这一点。等等。
为了强调这个想法的灵活性,以下是如何仅使用trait来完成上面列表中的所有操作:
Interfaces 接口
Logger
是一个具有两个方法的接口。它看起来与其他语言非常相似,只不过它显示的是 trait
而不是 interface
。
trait Logger {
fn log(&self, s: &str);
fn err(&self, e: &str);
}
struct StdoutLogger {
}
impl Logger for StdoutLogger {
fn log(&self, s: &str) {
println!("{}", s);
}
fn err(&self, e: &str) {
self.log(e);
}
}
fn run(l: &dyn Logger) {
l.log("Hello");
l.err("Oops");
}
fn main() {
let l = StdoutLogger {
};
run(&l);
}
很简单。
Abstract classes 抽象类
抽象类是不能直接实例化的,你必须扩展它来填充缺少的方法。在 Rust 中,这看起来像是具有默认实现的trait。继续上面的例子:
trait Logger {
fn log(&self, s: &str);
fn err(&self, e: &str