trait

Rust的trait与Scala的trait类似(可以理解为Java的interface,但也不能全这么理解)。trait可以翻译为特征

定义trait

trait Math {
    fn squares_sum(&self) -> f64;
}

&self表示的是函数的调用者的不可变引用。类似Python中的self或Javascript中的this。

只不过Rust中,&self必须在函数参数中显示声明。

为类型实现trait

trait只是定义了函数,并没有实现函数。实现代码交给具体实现它的类型去补充。

基本语法格式:

impl my_trait for my_struct {
    // 实现trait的方法。
}

例:为 struct Point 实现 Math trait。

struct Point {
    x:i32,
    y:i32
}

trait Math {
    fn squares_sum(&self) -> f64;
}

impl Math for Point {
    fn squares_sum(&self) -> f64 {
        (self.x*self.x + self.y*self.y) as f64
    }
}

使用上面定义的Circle,调用方法:

fn main() {
    let p = Point {x:10,y:20};
    println!("{}",p.squares_sum());
}

为基础类型实现trait

// 省略上面定义的部分。

impl Math for i32 {
    fn squares_sum(&self) -> f64 {
        ( *self * *self) as f64
    }
}

fn main() {
    let res = 10.squares_sum();
    println!("{}",res);
}

trait的默认方法

与Scala类似,trait可以有默认方法。

trait Foo {
    fn is_valid(&self) -> bool;

    fn is_invalid(&self) -> bool {
        !self.is_valid()
    }
}

在实现trait的代码中,可以重新实现trait的默认方法,也可以不实现默认方法。

trait的继承

使用:表示trait的继承关系。

trait A : B {    // A继承B。 
   // ... 
}

例:FooBar继承Foo。FooBar扩展了Foo的内容。

trait Foo {
    fn foo(&self);
}

trait FooBar : Foo {
    fn foobar(&self);
}

FooBar的实现者也要同时实现Foo:

struct Baz;

impl Foo for Baz {
    fn foo(&self) { println!("foo"); }
}

impl FooBar for Baz {
    fn foobar(&self) { println!("foobar"); }
}

自动实现特殊方法 derive属性

Rust提供了一个属性derive来自动实现一些trait,能被derive使用的trait包括:

  • Clone
  • Copy
  • Debug
  • Default
  • Eq
  • Hash
  • Ord
  • PartialEq
  • PartialOrd

例:Foo自动实现Debug trait。

#[derive(Debug)]
struct Foo;

fn main() {
    println!("{:?}", Foo);
}

Drop trait

Drop trait是Rust提供的一个非常特殊的trait。

Drop trait中有一个drop(&mut self)方法。若一个变量的类型实现了Drop trait,则在这种变量离开作用域后,会自动调用drop方法。

这有点类似于C++的析构函数。

需要注意两点:

  • Drop trait 无法为基础类型实现方法。
  • 多个变量离开作用域,drop方法调用顺序与变量声明顺序相反。(这与Go的defer语句类似。原因很简单,方法调用结束,变量出栈,先入后出。)
struct Point {
    x:i32,
    y:i32
}

impl Drop for Point {
    fn drop(&mut self) {
        println!("({:?},{:?}) has drop",(*self).x,(*self).y);
    }
}

fn main() {
    let p1 = Point {x:10,y:10};
    println!("point1 is ({},{})",p1.x,p1.y);

    let p2 = Point {x:20,y:20};
    println!("point2 is ({},{})",p2.x,p2.y);
}

打印输出:

point1 is (10,10)
point2 is (20,20)
(20,20) has drop
(10,10) has drop

results matching ""

    No results matching ""