[Rust]Trait

trait定义了某一个类型所具有的特定行为,跟Java中的抽象类有类似,但有一些区别。
trait中可以包含常量,函数和类型等。

Self

所有的trait都有一个隐藏的类型Self,代表实现当前trait的具体类型,trait中定义的函数,如果

  1. 第一个参数是Self类型
  2. 变量名字为self

这个参数被称为接收者,具有接收者参数的函数我们称之为“方法”,用变量实例加点(.)访问。没有接收者参数的函数,称之为“静态方法”,通过冒号(::)访问。
常见的self包装类型:self: Selfself: &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

你可能感兴趣的:([Rust]Trait)