Rust trait
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的更多相关文章
- 实践解析丨Rust 内置 trait:PartialEq 和 Eq
摘要:Rust 在很多地方使用了 traits, 从非常浅显的操作符重载, 到 Send, Sync 这种非常微妙的特性. Rust 在很多地方使用了 traits, 从非常浅显的操作符重载, 到 S ...
- Rust 内置 trait :PartialEq 和 Eq
GitHub: https://github.com/storagezhang Emai: debugzhang@163.com 华为云社区: https://bbs.huaweicloud.com/ ...
- Rust中的Trait
类似接口,但和php中的trait又有点不一样. pub trait Summary { fn summarize(&self) -> String; } pub struct NewA ...
- Rust <8>:lifetime 高级语法与 trait 关联绑定
一.生命周期关联:如下声明表示,'s >= 'c struct Parser<'c, 's: 'c> { context: &'c Context<'s>, } ...
- Rust的Drop Trait,相当于析构代码
退出前自动执行的代码. struct CustomSmartPointer { data: String, } impl Drop for CustomSmartPointer { fn drop(& ...
- Rust语言的多线程编程
我写这篇短文的时候,正值Rust1.0发布不久,严格来说这是一门兼具C语言的执行效率和Java的开发效率的强大语言,它的所有权机制竟然让你无法写出线程不安全的代码,它是一门可以用来写操作系统的系统级语 ...
- Rust 中的继承与代码复用
在学习Rust过程中突然想到怎么实现继承,特别是用于代码复用的继承,于是在网上查了查,发现不是那么简单的. C++的继承 首先看看c++中是如何做的. 例如要做一个场景结点的Node类和一个Sprit ...
- Rust 学习 0
安装Rust 后,本地有文档: file:///usr/local/share/doc/rust/html/index.html file:///usr/local/share/doc/rust/ht ...
- MIPS台OpenWrt在系统内的路由器Rust应用程序开发
笔者:Liigo(庄小莉) 迄今:2014年9一个月17日本 (9一个月29日更新,11一个月19日本再次更新.在最后可用更新) 原文链接:http://blog.csdn.net/liigo/art ...
随机推荐
- Qt中检查槽函数connect是否正确
环境:VS2017+Qt插件 一般情况下VS+QT环境下运行的QT程序输出信息需要在调试模式的输出栏可以看到,由于太多信息所以导致查看不方便(当然也可以在筛选选项中筛选信息). 有更方便查看输出信息的 ...
- 9. VUE 常用正则表达式
1. 判断输入是否是数字 var numReg = /^[0-9]+$/ var numRe = new RegExp(numReg) if (!numRe.test(number)) { this. ...
- Day01_05_Java第一个程序 HelloWorld - java类规则
第一个程序Hello World *基础语法规则: 1. 第一个Java程序 HelloWorld! public class HelloWorld{ public static void main( ...
- Typora配置PicGo时,提示Failed to fetch【Bug集中营】
Typora配置PicGo时,提示Failed to fetch 两者配置的端口不一致造成的 打开Typora,选择文件-偏好设置-图像-验证图片上传选项,点击验证图片上传选项 会提示错误:Faile ...
- ASP.Net 管道模型 VS Asp.Net Core 管道 总结
1 管道模型 1 Asp.Net Web Form管道 请求进入Asp.Net工作进程后,由进程创建HttpWorkRequest对象,封装此次请求有关的所有信息,然后进入HttpRuntime类进 ...
- SpringBoot自动装配,比较全的吧,来看看吧~
文章挺长,表达不好,希望能有获~~~~~~~ Spring也提供使用注解来注册bean,为什么要用SpringBoot呢? 使用Spring应用,比如SpringMVC还行需要配置ViewResolv ...
- vagrant构建centos虚拟环境
vagrant搭建centos 什么是vagrant 如何使用 1.构建本地的目录 2.官方下载对应的镜像文件,官方下载地址 3.导入刚刚下载的镜像(box文件) 4.初始化 5.修改Vagrantf ...
- MyBatisPlus入门学习
目录 MyBatisPlus 概述 快速入门 配置日志输出 CRUD拓展 插入 主键生成策略 更新操作 自动填充 乐观锁 查询操作 分页查询 删除操作 逻辑删除 性能分析插件 条件构造器 代码自动生成 ...
- 02- APP需求分析与APP测试流程
在展开一轮测试的时候,我们要遵循一个规范的流程. APP测试流程: 项目立项:简单介绍项目内容是什么? 需求评审:开发,测试,和产品. 分析需求:编写测试用例 测试用例评审:一般测试团队参加,测试点是 ...
- UVA11389巴士司机问题
题意: 有n个巴士司机,然后有2n个活,其中有n个是上午,n个是下午,每个自己都要选择一个上午的和一个下午的,每个活都有驾驶距离,如果一个司机每天的驾驶距离大于d,那么超出的部分就要每个单 ...