RUST 每日一省:trait种类

news/2024/11/30 0:36:15/

       trait的基本形式,很简单,但这只是trait的冰山一角。当你开始接触大型代码库中的trait时,将会遇到它的多种形式。种类繁多有助于我们完成复杂问题的建模。下面我们一次介绍其他形式的trait,以便了解何时需要使用它们。

标准trait 


这是trait定义的最简单形式。我们它作为trait定义进行了阐述:

trait Foo {fn foo();
}

标准库中的一个示例是 Default 特征,它主要是针对可以使用默认值初始化的类型实现的。

泛型trait


trait也可以是泛型。当用户希望为多种类型实现trait的情况下非常有用:

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

这样的例子是 From<T>,它们允许从某种类型转换为类型 T,反之亦然。例如下例,我们给Number实现了From<i32> trait,这意味着,所有的i32,都可以通过Number::from()函数转化为Number。

#[derive(Debug)]
struct Number {value: i32,
}impl From<i32> for Number {fn from(item: i32) -> Self {Number { value: item }}
}fn main() {let num = Number::from(30);println!("My number is {:?}", num);
}

关联类型trait

trait Contains<A, B> {fn contains(&self, _: &A, _: &B) -> bool; fn first(&self) -> i32; fn last(&self) -> i32; 
}//关联类型
trait Contains {type A;type B;fn contains(&self, _: &Self::A, _: &Self::B) -> bool;
}

        这是泛型trait的更好选择,因为它们能够在trait中声明相关类型。它们具有较少的类型签名,其优点在于,在实际的编程中,它们允许用户一次性声明关联类型,并在任何特征方法或函数中使用 Self::A 作为返回类型或参数类型。这消除了类型的冗余声明,与泛型trait的情况类似。关联类型trait的最佳用例之一是 Iterator 特征, 它用于迭代自定义类型的值。 在后边文章, 我们将会深入介探讨一下。

marker  trait


        在 std::marker 模块中定义的特征被称为marker  trait。这种trait不包含任何方法,声明时只是提供特征名称和空的函数体。其实我们之前介绍copy和clone时,就介绍了copy其实就是 marker trait。
        除了Copy,标准库中的示例还有Send、 Sync。它们被称为marker  trait,因为它们用于简单地将类型标记为属于特定的组群,以获得一定程度的编译期保障。标准库中的两个这样的示例是 Send 和 Sync 特征,它们在适当的时候由语言为大多数类型自动实现,并确定哪些值可以安全地发送和跨线程共享。我们将在后续文章对它们进行详细介绍。

父trait


Rust 没有“继承”,但是你可以将一个 trait 定义为另一个 trait 的超集(即父 trait)。例如:

trait Person {fn name(&self) -> String;
}// Person 是 Student 的父 trait。
// 实现 Student 需要你也 impl 了 Person。
trait Student: Person {fn university(&self) -> String;
}

        在上述代码片段中,我们声明了一个trait Student,它依赖于父级trait Person。在 Student的定义中,要求用户在为类型实现 Student特征时必须为 Person trait提供实现。标准库中的这样一个示例是 Copy trait,它要求类型必须实现 Clone trait。

派生trait

通过 #[derive] ,编译器能够提供某些 trait 的基本实现。如果需要更复杂的行为,这些 trait 也可以手动实现。

下面是标准库中一些可以自动派生的 trait:

  • 比较 trait: Eq,PartialEq,Ord,PartialOrd 
  • Clone, 用来从 &T 创建副本 T
  • Copy,使类型具有 “复制语义”(copy semantics)而非 “移动语义”(move semantics)。
  • Hash,从 &T 计算哈希值(hash)。
  • Default, 创建数据类型的一个空实例。
  • Debug,使用 {:?} formatter 来格式化一个值。


http://www.ppmy.cn/news/58426.html

相关文章

常见元件、封装、尺寸、表面处理等

参考&#xff1a;https://www.bilibili.com/read/cv11024927?fromsearch&spm_id_from333.337.0.0 参考&#xff1a;https://www.bilibili.com/read/cv18413169?fromsearch&spm_id_from333.337.0.0 目录 通孔插件技术(THT)和表面贴装技术(SMT)封装类型SOP/SOIC封装DIP…

国产中间件介绍

一、什么是中间件&#xff1f; 为解决分布异构问题&#xff0c;提出了中间件概念&#xff0c;中间件是位于平台&#xff08;硬件和操作系统&#xff09;和应用之间的通用服务&#xff0c;这些服务具有标准的程序接口和协议。针对不同的操作系统和硬件平台&#xff0c;有符合接口…

Java时间类(二)-- Date()类

目录 1. Date()的构造方法: 2. Date()的常用方法: Java 中的 Date 类代表时间戳,即从 1970 年 1 月 1 日 00:00:00 GMT 开始到现在的毫秒数。 1. Date()的构造方法: 方法名说明

CCD视觉检测设备如何选择光源

CCD视觉检测设备的机器视觉系统对光源的要求很高&#xff0c;光源是决定图像质量的一个重要因素。那么&#xff0c;我们就来看看CCD图像加网设备和机器视觉系统光源的选择点——CCD图像加网设备。 CCD视觉检测设备机器视觉系统光源选择要点&#xff1a; 1. 对比度&#xff1a;…

LeetCode周赛复盘(第343场周赛)

文章目录 1、 保龄球游戏的获胜者1.1 题目链接1.2 题目描述1.3 解题代码1.4 解题思路 2、找出叠涂颜元素2.1 题目链接2.2 题目描述2.3 解题代码2.4 解题思路 3、前往目标的最小代价(未来补充)3.1 题目链接3.2 题目描述3.3 解题代码3.4 解题思路 4、字典序最小的美丽字符串4.1 题…

Android APK 反编译后重新打包并签名

APKTool&#xff1a; Apktool 是一个逆向android非常有用的工具&#xff0c;可以用来反编译apk文件&#xff0c;并且能在修改部分资源文件后&#xff0c;重新打包成一个新的apk。 下载连接&#xff1a;http://ibotpeaches.github.io/Apktool/install/ 下载之后文件夹非常清爽&…

8年测试老鸟谈,性能测试-测试环境搭建与常见问题,这些你都知道吗?

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 一个问题&#xf…

C语言文件操作【基础知识 + 顺序读写 + 文件版通讯录】

全文目录 &#x1f600; 前言&#x1f914; 什么是文件&#x1f636; 程序文件&#x1f636; 数据文件&#x1f636; 文件名 &#x1f928; 文件指针&#x1f92b; 文件的打开和关闭&#x1f611; fopen 打开文件&#x1f4d9; **mod的规律&#xff1a;** &#x1f611; fclose…