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,更多的是组合的概念,特斯拉是车子,首先他得有轮子属性

Rust trait的更多相关文章

  1. 实践解析丨Rust 内置 trait:PartialEq 和 Eq

    摘要:Rust 在很多地方使用了 traits, 从非常浅显的操作符重载, 到 Send, Sync 这种非常微妙的特性. Rust 在很多地方使用了 traits, 从非常浅显的操作符重载, 到 S ...

  2. Rust 内置 trait :PartialEq 和 Eq

    GitHub: https://github.com/storagezhang Emai: debugzhang@163.com 华为云社区: https://bbs.huaweicloud.com/ ...

  3. Rust中的Trait

    类似接口,但和php中的trait又有点不一样. pub trait Summary { fn summarize(&self) -> String; } pub struct NewA ...

  4. Rust <8>:lifetime 高级语法与 trait 关联绑定

    一.生命周期关联:如下声明表示,'s >= 'c struct Parser<'c, 's: 'c> { context: &'c Context<'s>, } ...

  5. Rust的Drop Trait,相当于析构代码

    退出前自动执行的代码. struct CustomSmartPointer { data: String, } impl Drop for CustomSmartPointer { fn drop(& ...

  6. Rust语言的多线程编程

    我写这篇短文的时候,正值Rust1.0发布不久,严格来说这是一门兼具C语言的执行效率和Java的开发效率的强大语言,它的所有权机制竟然让你无法写出线程不安全的代码,它是一门可以用来写操作系统的系统级语 ...

  7. Rust 中的继承与代码复用

    在学习Rust过程中突然想到怎么实现继承,特别是用于代码复用的继承,于是在网上查了查,发现不是那么简单的. C++的继承 首先看看c++中是如何做的. 例如要做一个场景结点的Node类和一个Sprit ...

  8. Rust 学习 0

    安装Rust 后,本地有文档: file:///usr/local/share/doc/rust/html/index.html file:///usr/local/share/doc/rust/ht ...

  9. MIPS台OpenWrt在系统内的路由器Rust应用程序开发

    笔者:Liigo(庄小莉) 迄今:2014年9一个月17日本 (9一个月29日更新,11一个月19日本再次更新.在最后可用更新) 原文链接:http://blog.csdn.net/liigo/art ...

随机推荐

  1. Qt中检查槽函数connect是否正确

    环境:VS2017+Qt插件 一般情况下VS+QT环境下运行的QT程序输出信息需要在调试模式的输出栏可以看到,由于太多信息所以导致查看不方便(当然也可以在筛选选项中筛选信息). 有更方便查看输出信息的 ...

  2. 9. VUE 常用正则表达式

    1. 判断输入是否是数字 var numReg = /^[0-9]+$/ var numRe = new RegExp(numReg) if (!numRe.test(number)) { this. ...

  3. Day01_05_Java第一个程序 HelloWorld - java类规则

    第一个程序Hello World *基础语法规则: 1. 第一个Java程序 HelloWorld! public class HelloWorld{ public static void main( ...

  4. Typora配置PicGo时,提示Failed to fetch【Bug集中营】

    Typora配置PicGo时,提示Failed to fetch 两者配置的端口不一致造成的 打开Typora,选择文件-偏好设置-图像-验证图片上传选项,点击验证图片上传选项 会提示错误:Faile ...

  5. ASP.Net 管道模型 VS Asp.Net Core 管道 总结

    1 管道模型  1 Asp.Net Web Form管道 请求进入Asp.Net工作进程后,由进程创建HttpWorkRequest对象,封装此次请求有关的所有信息,然后进入HttpRuntime类进 ...

  6. SpringBoot自动装配,比较全的吧,来看看吧~

    文章挺长,表达不好,希望能有获~~~~~~~ Spring也提供使用注解来注册bean,为什么要用SpringBoot呢? 使用Spring应用,比如SpringMVC还行需要配置ViewResolv ...

  7. vagrant构建centos虚拟环境

    vagrant搭建centos 什么是vagrant 如何使用 1.构建本地的目录 2.官方下载对应的镜像文件,官方下载地址 3.导入刚刚下载的镜像(box文件) 4.初始化 5.修改Vagrantf ...

  8. MyBatisPlus入门学习

    目录 MyBatisPlus 概述 快速入门 配置日志输出 CRUD拓展 插入 主键生成策略 更新操作 自动填充 乐观锁 查询操作 分页查询 删除操作 逻辑删除 性能分析插件 条件构造器 代码自动生成 ...

  9. 02- APP需求分析与APP测试流程

    在展开一轮测试的时候,我们要遵循一个规范的流程. APP测试流程: 项目立项:简单介绍项目内容是什么? 需求评审:开发,测试,和产品. 分析需求:编写测试用例 测试用例评审:一般测试团队参加,测试点是 ...

  10. UVA11389巴士司机问题

    题意:       有n个巴士司机,然后有2n个活,其中有n个是上午,n个是下午,每个自己都要选择一个上午的和一个下午的,每个活都有驾驶距离,如果一个司机每天的驾驶距离大于d,那么超出的部分就要每个单 ...