Rust Trait

Rust 第16节 Trait

Trait 告诉编译器
某种类型具有那些并且可以与其他类型共享的功能
它的本质就是
不同类型具有的相同行为

声明一个trait

关键字 trait;只有方法签名,没有方法实现

pub trait Animal {// trait 的声明,一个trait中可以有多个方法fn say(&self) -> String;fn func1(&self){};fn func2(&self){};
}

实现该Trait 的类型,必须提供具体的方法实现;
即 类型要和Trait进行关联;
例如:

pub struct Dog {pub name : String,pub age : i32,
}impl Animal for Dog {   //将该类型使用traitfn say(&self) -> String {format!("my name is {}",self.name)}
}

其他类型也可以跟这个Trait进行关联

pub struct Cat {pub name : String,pub age : i32,pub fun : String,
}impl Animal for Cat {fn say(&self) -> String {format!("my name is {},my age is {}",self.name,self.age)}}

调用

    let d1 = Dog{name : "Tom".to_string(),age : 3,};let c1 = Cat {name : "Goj".to_string(),age : 2,fun : "xx".to_string(),};println!("{}",d1.say());println!("{}",c1.say());

注意:
这个类型 或者 这个 trait是本地定义的;
无法为外部类型 实现外部trait

Trait 的默认实现方法

pub trait Animal {// trait 的声明,一个trait中可以有多个方法fn say(&self) -> String;fn hello(&self) {  //默认实现的方法println!("hello everyone!!");}fn goodbye(&self){println!("{},goodbye !!",self.say());  //默认实现的方法可以调用其他方法,即使这个方法不是默认实现的方法}  
}

对于跟Trait关联的类型;可以对默认函数进行重新定义,即重构

impl Animal for Cat {fn say(&self) -> String {format!("my name is {},my age is {}",self.name,self.age)}fn hello(&self) { //在这个类型中,对默认方法进行了重构println!("hello everyone ,i'm {}",self.name);}
}

也可以不改变,使用默认方法

impl Animal for Dog {   //将该类型使用traitfn say(&self) -> String {format!("my name is {}",self.name)}//在这个类型中,没有对trait的hello方法进行重构,所以使用的是默认的实现
}

Trait 作为参数

期望这个函数的参数是有Animal trait功能的类型

方法1 impl Trait 语法 使用于简单类型

pub fn speek(item : impl Animal) {println!("this is me, {}",item.say());
}
   speek(c1);speek(d1);

方法2 Trait bound 语法

直译就是Trait 约束,适用于比较复杂的场景

pub fn speek_v2<T: Animal>(item : T) {println!("V2: {}",item.say());
}
//复杂场景
pub fn speek_v3<T:Animal>(item1 : T,item2 : T) {println!("v3: {},{}",item1.say(),item2.say());
}
    speek_v2(c1);speek_v2(d1);speek_v3(d1, d2);

需要参数同时支持多个Trait

期望这个函数的参数是同时支持两个trait功能的类型
使用 + 号,来表示同时支持多个trait

pub fn two_speek(item : impl Animal + Funcitons) {println!("{}",item.say());item.my_function();
}

trait bound

pub fn two_speek_v2<T:Animal + Funcitons>(item : T ) {println!("{}",item.say());item.my_function();
}

当有更复杂场景时,使用where约束

pub fn speek_v4<T : Animal,U : Animal + Funcitons>(item1 : T,item2 : U) {item1.goodbye();item2.my_function();
}

where 约束

pub fn speek_v5<T,U>(item1 : T,item2 : U) 
whereT : Animal,U : Animal + Funcitons,
{item1.goodbye();item2.my_function();
}

Trait 作为返回值

注意点,这个函数只能返回某一种具体的类型;返回可能得不同的类型,编译器会报错

pub fn create_animal(s : &str) -> impl Animal{Dog {name : String::from("s"),age : 12,}
}

泛型 加 Trait

定义一个泛型结构体

struct Pair<T> {x : T,y : T,
}

针对所有泛型T,定义一个方法:

impl<T> Pair<T> {fn new(x :T ,y : T) -> Self {Self {x , y}}  //这个泛型结构体有一个new 函数
}

针对满足要求的Trait类型,定义一个方法:

impl<T : Display + PartialOrd> Pair<T> {  
// 这里对泛型结构体中的 cmp_display() 方法进行了约束,只有类型T 满足 Display 和 PartialOrd 两个Trait时,才能有这个方法。fn cmp_display(&self) {if self.x >= self.y {println!("largest member is {}",self.x);} else {println!("largest member is {}",self.y);}}
}

覆盖约束

满足某一约束条件然后去实现另一Trait 的行为叫覆盖约束
例如to_string()方法
3.to_string();
数字3 可以调用to_string()方法,
是由于 3 有 display方法,
所有有display方法的类型,都被实现了 to_string 方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502748.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++ string类的常用方法_【常用类方法】Object

Object类的知识点总结概述&#xff1a;1. Object类是所有其他类的父类2. Object类只有一个构造方法&#xff0c;这也是为什么所有子类在调用构造方法时都会默认先调用父类的无参构造方法3. Object类没有成员变量方法&#xff1a;1. public int hashCode()2. public final Class…

android 收获地址管理,android UiAutomator添加收货地址的用例

本人在学习UiAutomator的时候&#xff0c;遇到添加收获地址的测试用例&#xff0c;这里的地址的地区是一级一级选择的。所以写了一个随机选择的方法。分享出来&#xff0c;供大家参考。public void addAdress() throws UiObjectNotFoundException {login();waitForResourceIdAn…

python注释以符号什么开始_python注释以什么符号开始

python注释以什么符号开始,注释,中文,代码,批量,符号 python注释以什么符号开始 易采站长站&#xff0c;站长之家为您整理了python注释以什么符号开始的相关内容。 python中的注释有多种&#xff0c;有单行注释&#xff0c;多行注释&#xff0c;批量注释&#xff0c;中文注释也…

verilog 移位运算符 说明_Verilog学习笔记基本语法篇(二)·········运算符...

Verilog HDL的语言的运算符的范围很广&#xff0c;按照其功能大概可以分为以下几类:(1)算术运算符&#xff0c;-&#xff0c;*&#xff0c;/&#xff0c;%优先顺序&#xff01;~* / % -<< >>< < > > ! !&^ ^~|&&||&…

linux 别名,Linux中的别名就这么简单,如何使用和创建永久别名?

原标题&#xff1a;Linux中的别名就这么简单&#xff0c;如何使用和创建永久别名&#xff1f;输入文本和记命令是Linux命令行爱好者的缺点之一。如果你需要输入并记住同样长的命令&#xff0c;这可能会降低终端的工作效率。如果您可以用自己的短名称替换长命令&#xff0c;或者…

华为手机如何固定横屏_华为手机如何录屏?原来方法这么简单,手把手教你学会...

很多人都不知道&#xff0c;华为手机到底如何录屏&#xff0c;下面给大家分享4种方法&#xff0c;非常简单&#xff0c;手把手教你学会。一、通知栏录屏从手机顶端往下滑动打开通知栏&#xff0c;这个面板上有很多快捷功能&#xff0c;其中就有【屏幕录制】功能&#xff0c;点击…

程序发出的广播其他程序收不到_RabbitMQ 如何实现对同一个应用的多个节点进行广播...

1.背景了解过RabbitMQ的Fanout模式&#xff0c;应该知道它原本的Fanout模式就是用来做广播的。但是它的广播有一点区别&#xff0c;来回顾下它的含义&#xff1a;Fanout类型没有路由键的概念&#xff0c;只要队列绑定到了改exchange上面&#xff0c;就会接收到所有的消息。使用…

android listview高级,Android 高级控件笔记-列表视图ListView 基本适配器BaseAdapter

我最近做项目用到了基本适配器BaseAdapter&#xff0c;所以写篇博客总结一下&#xff0c;希望也能对你有所帮助什么时候用BaseAdapter(同一项存在多个控件&#xff0c;复杂的列表时)Android中Adapter类其实就是把数据源绑定到指定的View上&#xff0c;然后再返回该View&#xf…

cnn生成图像显著图_基于CNN与图像前背景分离的显著目标检测

基于CNN与图像前背景分离的显著目标检测东野长磊;万文鑫【期刊名称】《软件导刊》【年(卷),期】2020(019)001【摘要】为了解决计算机视觉模拟人眼的视觉机制,显著性目标检测DSS(DeeplySupervisedSalient)在某个场景中人眼首先观察到的目标.基于卷积神经网络和图像前背景分离算法…

api 创建zookeeper客户端_一文了解 Zookeeper 基本原理与应用场景

Zookeeper 是一个高性能、高可靠的分布式协调系统&#xff0c;是 Google Chubby 的一个开源实现&#xff0c;目前在分布式系统、大数据领域中使用非常广泛。本文将介绍 Zookeeper 集群架构、数据模型、监听机制&#xff0c;以及Zookeeper典型的应用场景等。1. Zookeeper 集群角…

mysql操作json优点和缺点_SQL-mysql操作json

一 前言MySQL 5.7.8 之后 支持 JSON (由rfc7159规定)数据类型&#xff0c;其能在字段中使用json 类型&#xff0c;做到了自动校验是否为json类型数据&#xff0c;否则插入数据会报异常&#xff1b;其次&#xff0c;储存json数据内部做到了优化储存&#xff0c;能够快速读取json…

android多个水波球,android球形水波百分比控件代码

本文主要介绍的是一个球形水波的百分比控件&#xff0c;市面上有各种形形色色的百分比控件&#xff0c;我一直觉得水波是最炫的&#xff0c;UI给了我这个机会&#xff0c;然而网上搜了一大堆&#xff0c;不是太复杂&#xff0c;代码太多(反正我是调不出效果来)&#xff0c;就是…

python数据去重的函数_python pandas dataframe 去重函数的具体使用

今天笔者想对pandas中的行进行去重操作&#xff0c;找了好久&#xff0c;才找到相关的函数 先看一个小例子 from pandas import Series, DataFrame data DataFrame({k: [1, 1, 2, 2]}) print data IsDuplicated data.duplicated() print IsDuplicated print type(IsDuplicate…

合信达 机器人_【中信建投 通信】拓邦股份:中报电话会议干货纪要

原标题&#xff1a;【中信建投 通信】拓邦股份&#xff1a;中报电话会议干货纪要一中信建投通信行业分析师 闫慧辰首先非常感谢大家参加我们举办的拓邦股份2017年中报解读电话会议。拓邦股份是我们5月份开始重点推荐的标的之一。我们观察到了公司业绩的爆发增长&#xff0c;同时…

android 3.0单元测试,Android Studio 3.0 gradle 3.0.0-beta2打破了Kotlin单元测试覆盖率?

我有一个简单的Kotlin课程,如下所示class MyClass {fun justSayHello(yes: Boolean): String {if (yes) {return "Hello"} else {return "Sorry"}}}我有我的测试(这里用Java编写,也可以在Kotlin中)public class MyClassTest {private MyClass myClass new…

c++ 二维数组_【技术篇】C指针与二维数组深度辨析

一、源代码/*第01行*/ CLion 2019.3.4 x64中编写的源代码截图二、深度辨析CLion 2019.3.4 x64中编译的结果截图zippo[4][2]是一个四行二列的int型二维数组①不论一维数组还是二维数组&#xff0c;数组名就是指向数组首个元素的指针&#xff0c;也即数组名就是数组首个元素的…

numberformate php_php number_format函数怎么用?

number_format函数是PHP中的一个内置函数&#xff0c;用于格式化一个包含数千个分组的数字&#xff0c;其语法是“string number_format ( $number, $decimals, $decimalpoint, $sep )”。本篇文章主要给大家介绍php number_format用法&#xff0c;希望对需要的朋友有所帮助&am…

android 脚本模拟点击屏幕,android 脚本模拟点击屏幕,android模拟

android 脚本模拟点击屏幕&#xff0c;android模拟对低概率问题&#xff0c;需要多次测试以复现问题&#xff0c;使用脚本更容易实现&#xff0c;避免频繁人工操作首先要了解手机的众多输入设备&#xff1a;命令&#xff1a;adb shell cat /proc/bus/input/devices/I: Bus0000 …

shiro启动之后页面访问不了_java:shiro入门——4

【7】测试【7.1】启动点击apply然后点击OK【7.2】登录过滤访问http://localhost:8080/platform/home的时候&#xff0c;会被【7.3】角色过滤使用“admin”用户登录&#xff0c;密码&#xff1a;123根据SecurityServiceImpl我们可以知道使用admin账号登录成功之后&#xff1a;此…

Android如何分析native代码,使用android-ndk-profiler对native代码进行性能分析

android-ndk-profiler需要使用gcc进行编译&#xff0c;从NDK r13b 起NDK使用的默认编译器从gcc换成了clang&#xff0c;官方提供了Simpleperf工具进行性能分析&#xff0c;具体情况可以参考https://developer.android.google.cn/ndk/guides/simpleperf 。下载使用编译方面的改动…