Rust語言開發基礎(八)Rust的接口及其實現

trait(特徵)相似於其餘語言中的interface或者protocol,指定一個實際類型必須知足的功能集合git

1、如何理解trait,能夠從咱們所瞭解的接口特性去推斷trait的用法github

1. 那麼做爲一個類接口的關鍵字,意味着被它修飾的類不包含實現的方法fn,只定義函數名稱和參數,由這個類的實現類去完成它的方法。
2. 任何實現接口的類都必須去實現接口的方法,這種特性剛好能夠做爲一種從上到下的約束,應用到Rust語法裏面。
3. 接口也能夠不斷被繼承,最後實現類需要實現全部的接口裏的方法。
函數

 

2、trai的實現方式工具

1. 定義接口開發工具

trait HasArea {
    fn area(&self) ->f64;
}
spa

 

2. 實現接口繼承

爲一個結構體圓增長一個計算圓面積的函數:
接口

struct Circle {
    x:f64,
    y:f64,
    radius:f64,
}
ci

impl HasAreaforCircle {
    fn area(&self) ->f64 {
        std::f64::consts::PI* (self.radius *self.radius)
    }
}
開發

----------------------------------------------------------

fn main() {
    let c =Circle {
        x:0.0f64,
        y:0.0f64,
        radius:1.0f64,
    };
    println!("circle c has an area of {}", c.area());
}


最終輸出:
circle c has an area of 1


3. 繼承接口
trait Foo {
    fn foo(&self);
}

trait FooBar:Foo {
    fn foobar(&self);
}
實現:
struct Baz;

impl FooforBaz {
    fnfoo(&self) { println!("foo"); }
}

impl FooBarforBaz {
    fn foobar(&self) { println!("foobar"); }
}

 

4.自動化實現接口
Rust會自動幫你實現接口,固然必須是某些特定的接口方法,就好像利用開發工具幫你實現一些接口方法同樣。
能幫你實現的方法僅限於:Clone,Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd
這些方法通常是常見的方法,要自動實現上述方法,前提是使用derive屬性。

#[derive(Debug)]structFoo;

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

5.自帶默認方法
tait修飾的類都自動被系統加上一個默認方法,這個默認方法不要求被實現類實現,固然實現類能夠去實現它並覆蓋原有方法。

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

    fn is_invalid(&self) ->bool { !self.is_valid() }
}
is_invalid是默認方法,Foo的實現者並不要求實現它,若是選擇實現它,會覆蓋掉它的默認行爲。

 

3、Rust裏面的應用場景

1.給泛型增長約束,或者說給泛型增長實現要求。
例如:Debug是Rust內置的一個trait,爲"{:?}"實現打印內容,函數foo接受一個泛型做爲參數,而且約定其須要實現Debug
use std::fmt::Debug;

fn foo<T:Debug>(s:T) {
    println!("{:?}", s);
}


2.給泛型增長多個trait,也即所謂的多重約束。

use std::fmt::Debug;

fn foo<T:Debug+Clone>(s:T) {
    s.clone();
    println!("{:?}", s);
}
<T: Debug + Clone>中Debug和Clone使用+鏈接,表示泛型T須要同時實現這兩個trait。

 

3. where關鍵字其實只是爲多重約束增長一些寫法。

標準寫法:
use std::fmt::Debug;

fn foo<T:Clone,K:Clone+Debug>(x:T, y:K) {
    x.clone();
    y.clone();
    println!("{:?}", y);
}
where從句寫法一:
fn foo<T,K>(x:T, y:K) whereT:Clone,K:Clone+Debug {
    x.clone();
    y.clone();
    println!("{:?}", y);
}
where從句寫法二:
fn foo<T,K>(x:T, y:K)
    whereT:Clone,K:Clone+Debug {
    x.clone();
    y.clone();
    println!("{:?}", y);
}
語法糖,這只是語法糖!

 

4.孤僻的應用場景,給內置類型增長trait

trait HasArea {
    fn area(&self) ->f64;
}

impl HasAreafori32 {
    fn area(&self) ->f64 {
        *selfasf64
    }
}

area();


最後的輸出接口f64類型的數值,這個方法至關有用

注意:
1. 當你爲某類型實現某 trait 的時候,必需要求類型或者 trait 至少有一個是在當前 crate 類庫中定義的。你不能爲第三方的類型實現第三方的 trait 。
2. 在調用 trait 中定義的方法的時候,必定要記得讓這個 trait 可被訪問。

 

參考:https://github.com/rustcc/RustPrimer/blob/master/10-trait/10-00-overview.md

相關文章
相關標籤/搜索