Rust系列-2.特征Trait

泛型

泛型是一种参数化多态,使用泛型可以编写更为抽象的代码,减少工作量,简单来说,泛型就是把一个泛化的类型作为参数,单个类型可以抽象化为一簇类型。
rust在编译时期会把泛型枚举,函数,结构体单态化

单态化意味着编译器要将一个泛型函数生成多个具体类型对应的函数。
单态化是编译器进行静态分发的一种策略。
单态化静态分发的好处是性能好,没有运行时开销,缺点是容易造成编译后生成的二进制文件膨胀。

trait是在行为上对类型的约束。

使用场景
接口抽象,接口是对类型行为的统一约束
泛型约束,泛型的行为被trait限定在更有限的范围内
抽象类型,在运行时作为一种间接的抽象类型去使用,动态的分发给具体的类型
标签trait,对类型的约束,可以直接作为一种“标签”使用。

接口抽象

trait最基本的用法就是进行接口抽象,它有如下特点:

  • 接口中可以第一方法,并支持默认实现
  • 接口中不能实现另一个接口,但是接口之间可以继承
  • 同一个接口可以同时被多个类型实现,但不能被同一个类型实现多次
  • 使用impl关键字为类型实现接口方法
  • 使用trait关键字来定义接口

trait关联类型

使用关联类型能够是代码变得更加精简,同时也对方法的输入和输出进行来更好的隔离,使得代码的可读性大大增强。在语义层面上,使用关联类型也增强来trait表示行为的这种语义,因为它表示来和某个行为(trait)相关联的类型,在工程上也提现了高内聚的特点。

孤儿规则
孤儿规则规定,如果实现某个trait,那么该trait和要实现该trait的那个类型至少有一个要在当前create中定义。

trait继承

子trait可以继承父trait中定义或实现的方法。
trait后面的冒号代表trait继承,其后跟随要继承的父trait名称,如果是多个trait则用加号相连;

泛型约束

trait限定

使用trait对泛型进行约束叫trait限定。
在泛型中使用trait限定可以将任意类型的范围根据类型的行为限定到更加精确可控的范围内。
trait可以使用where关键字对较多的限定的代码进行重构。

在作为泛型限定时,Rust中冒号代表集合的“包含于”关系,而加号代表这种限定行为交集。
trait限定给予了开发者更大的自由度,因为不再需要类型间的继承,也简化了编译器的检查操作,包含trait限定的泛型属于静态分发,在编译期通过单态化分别生成具体类型的实例,所以调用trait限定中的方法也都是运行是零成本的,因为不需要在运行时进行方法查找。

抽象类型

抽象类型属于类型系统的一种,也叫存在类型,相对于具体类型而言,抽象类型无法直接实例化,它的每个实例都是具体类型的实例。
对于抽象类型而言,编译器可能无法确定其确切的功能和所占的空间大小,所以rust目前有两种方法来处理抽象类型,trait对象impl trait

trait对象

trait对象是对具有相同行为的一组具体类型的抽象,将共同拥有相同行为的类型集合抽象为一个类型。
traitObject包含两个指针:data指针vtable指针

impl trait

impl Trait只可以在输入的参数和返回值这两个位置使用。
impl trait用在参数位置时等价于使用trait限定的泛型。impl trait用在返回值位置的时候等价于给返回值类型增加一种trait限定范围。

标签trait

rust一共提供了5个重要的标签trait,都被定义在标准库std::marker模块中

  • Sized trait,用来标示编译期可确定大小的类型
  • Unsize trait,目前该trait为实验特性,用于标示动态大小类型
  • Copy trait,用来标示可以安全地按位复制其值的类型。
  • Send trait,用来标示可以跨线程安全通信的类型
  • Sync trait,用来标示可以在线程间安全共享引用的类型。

Copy trait

copy 是一个标签trait,编译器做类型检查时会检测类型所带来的标签,以验证它是否“合格”,copy的行为是一个隐式行为,开发者不能重载copy行为,它永远都是一个简单的位复制。
并非所有类型都可以实现copy trait ,对于自定义类型来说,必须让所有的成员都实现了copy trait这个类型才有资格实现copy trait。
clone trait是一个显式行为,任何类型都可以实现clone trait

Send trait 和Sync trait

rust提供了语言级的并发支持,rust凭借Send、Sync和所有权机制,在编译时期就检查出线程安全问题,保证了无数据竞争的的并发安全问题,让开发者可以“无恐慌”地编写多线程并发代码。
rust提供了Send和Sync两个标签trait,它们是rust无数据竞争开发的基石。
实现send的类型,可以安全地在线程间传递值,也就是说可以跨线程传递所有权。
实现了sync的类型,可以跨线程安全地传递共享(不可变)引用。

send 和sync标签trait和前面所说的copy,sized一样,内部也没有具体的方法实现,它们仅仅是标记可以安全的跨线程传递和访问的类型用send和sync标记,否则使用!send 和!sync标记

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容