• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Rusttrait

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

Rust trait

Rust中的trait类似于Java中的接口,定义了一组可以被类型选择实现的“契约”或共享行为,。

特征定义:

trait Playable{
    fn play(&self);
    fn pause(){
        println!("Paused");
    }
}

上述是一个简单trait定义,提供了两个方法,一个用于提供播放功能,一个用于提供暂停功能。

实现trait:

struct Audio(String);
struct Vedio(String);
impl Playable for Audio {
    fn play(&self) {
        println!("Audio play");
    }
}
impl Playable for Vedio {
    fn play(&self) {
        println!("Vedio play");
    }
}

上述用两个结构体Audio和Vedio分别实现了Playable接口

或许你已经注意到我们只实现了一个play方法,并没有在“实现”pause方法,其实他们是不同的两种方法。

trait方法

trait中可以有两种方法:

关联方法:

类似于Java中的静态方法,可以直接类型调用

实例方法:

以self/&self/&mut self作为第一个参数的方法,如果没有默认实现需要实现者提供实现,通过实例变量调用

调用trait方法:

fn main() {
    let audio=Audio(String::from("audio"));
    audio.play();
    Audio::pause();
    let vedio=Vedio(String::from("vedio"));
    vedio.play();
    Vedio::pause();
}

输出结果:

Audio play
Paused
Vedio play
Paused

当然,我们也可以重新实现关联方法:

impl Playable for Audio {
    fn play(&self) {
        println!("Audio play");
    }

    fn pause(){
        println!("Audio Paused");
    }
}

调用部分代码不变,结果如下:

Audio play
Audio Paused
Vedio play
Paused

trait 分类

标记特征

在std::marker模块定义的特征被称为标记特征,这种特征不包含任何方法,声明时只是提供特征名称和{},例如标准库提供的Copy,Send,Sync

泛型特征

特征也可以是泛型的:

pub trait From<T> {
    fn from(t:T)->Self;
}

实现:

#[derive(Copy,Clone)]
struct A(i32);
impl From<String> for A{
    fn from(t:String)->Self {
        A(t.len() as i32)
    }
}

介绍泛型时再具体讲解

关联类型特征
trait Foo{
    type Out;
    fn get_value(self)->Self::Out;
}

这提供了一种比泛型特征更好的选择,因为可以在特征中声明相关类型而不用使用泛型签名

这里Out由实现trait实现时指定,Self是具体实现类型的别名,Self::Out是关联类型Out的类型,下面是关联类型trait的一个实现:

#[derive(Copy,Clone)]
struct A(i32);
impl Foo for A {
    type Out = i32;

    fn get_value(self)->Self::Out {
        self.0
    }
}
继承特征

特征也可以在声明中表明它们依赖于其他特征,这被叫做特征继承。

举例:

trait Vehicle{
    fn get_price(&self)->u64;
}
trait Car:Vehicle{
    fn model(&self)->String;
}

trait Car 的声明表示它需要依赖trait Vehicle,下面我们来实现它们看看会发生什么:

struct TeslaRoadster{
    modle:String,
    release_date:u16,
}
impl Car for TeslaRoadster {
    fn model(&self)->String {
        todo!()
    }
}

这乍一看好像没什么错,但是编译会报如下错误:

显而易见,这表明我们要实现Car的前提是先实现它的依赖trait,即Vehicle,按照编译器提示作出修改:

struct TeslaRoadster{
    modle:String,
    release_date:u16,
}
impl Vehicle for TeslaRoadster {
    fn get_price(&self)->u64 {
        todo!()
    }
}
impl Car for TeslaRoadster {
    fn model(&self)->String {
        todo!()
    }
}

这样就满足了特征继承的要求

需要注意的是这里的特征继承只是一个习惯性叫法,只是对特征的实现作出了约束,实现一个trait必须要实现它所依赖的trait,更多的是组合的概念,特斯拉是车子,首先他得有轮子属性


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
玩弄SDR的历程(四)——充了个网盘会员开始用matlab?发布时间:2022-07-18
下一篇:
LinuxMatlabmexgcc版本发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap