trait定义了某一个类型所具有的特定行为,跟Java中的抽象类有类似,但有一些区别。
trait中可以包含常量,函数和类型等。
Self
所有的trait都有一个隐藏的类型Self
,代表实现当前trait的具体类型,trait中定义的函数,如果
- 第一个参数是
Self
类型 - 变量名字为
self
这个参数被称为接收者,具有接收者参数的函数我们称之为“方法”,用变量实例加点(.)访问。没有接收者参数的函数,称之为“静态方法”,通过冒号(::)访问。
常见的self
包装类型:self: Self
,self: &Self
, self: &mut Self
,简化写法:self
, &self
, &mut self
trait A {
fn method1(self: Self);
fn method2(self: &Self);
fn method3(self: &mut Self);
}
trait A {
fn method1(self);
fn method2(&self);
fn method3(&mut self);
}
方法
trait中的方法可以包含默认实现,实现这个trait的类型可以选择继承
或者重写
这个方法。
trait B {
fn m1(self: Self);
fn m2(self: &Self);
fn m3(self: &mut Self) {
println!("&Self");
}
}
struct A {
n: usize
}
impl B for A {
fn m1(self: Self) {
println!("Self");
}
fn m2(self: &Self) {
println!("&Self");
}
}
fn main() {
let a = A {n:1};
a.m1();
let b = A {n:2};
b.m2();
let mut c = A {n:3};
c.m3();
}
静态方法
没有接收者参数的函数称之为静态方法
扩展方法
可以给其他类型添加方法,即使这个类型不是当前crate的,但有如下原则:impl
要么跟trait在同一个crate,要么跟类型在同一个crate。否则,编译器报错。
trait Plus {
fn plus_one(&self) -> Self;
}
impl Plus for i32 {
fn plus_one(&self) -> i32 { *self + 1 }
}
fn main() {
let x : i32 = 1.plus_one();
// 输出结果 2
println!("{}", x);
}
默认实现trait
通过#[derive(...)]
让编译器自动添加实现某个trait
#[derive(Copy, Clone)]
Rust可以自动derive的trait
Debug Clone Copy Hash RustcEncodable RustcDecodable PartialEq Eq
ParialOrd Ord Default FromPrimitive Send Sync
网友评论