trait就是一种功能,比如,有一个自定义的mytrait trait, 你可以在mytrait里说要实现任何功能(函数);同时你也可以为所需要的对象进行实现(即impl mytrait for any)(注:Copy trait特殊除外)。-------这是你的权利
但是,你不一定可以说,让实现mytrait功能形成特定对象(&mytrait)。-------你要承担一些义务
即对象安全所尽的义务。
从某个角度上讲,trait的可以分安全对象的trait,和非安全对象的trait,只有安全对象的trait,才有资格带上&。比如,你看不到&Clone或Box < Clone>

此前,碰到这种情况,代码如下:

#[derive(Clone)]
struct Trade(i32);
trait Bet{fn bet(&self);
}
trait Test :Betfn test(&self);
}impl Test for Trade{fn test(&self){}
}impl Trade{fn default(&self) -> Vec<Box<dyn Test>>{let mut v = Vec::new();let trade = Trade(0);v.push(Box::new(trade) as Box<dyn Test > );v}
}

这个是没有问题的。

但是,如果把Test改一下:

trait Test :Sendfn test(&self);
}

但Clone,Sized加上去都会报错。

1、Send+ Sync与Clone、Sized

#[derive(Clone)]
struct Trade(i32);
trait Bet{fn bet(&self);
}
trait Test :Send+Sync //而不是Clone和Sizedfn test(&self);
}impl Test for Trade{fn test(&self){}
}impl Trade{fn default(&self) -> Vec<Box<dyn Test>>{let mut v = Vec::new();let trade = Trade(0);v.push(Box::new(trade) as Box<dyn Test > );v}
}

但是,如果是,Sized、Clone组合,仍会报错。

2、object-safe trait 问题

trait object 它不仅包括指向真实对象的指针,还包括一个指向虚函数表的指针。因此,并不是所有的trait都能作为trait对象使用的。

只有 对象安全(object safe)的 trait 才可以组成 trait 对象。trait的方法满足以下两条要求才是对象安全的:

(1)返回值类型不为 Self
(2)方法没有任何泛型类型参数

典型的安全对象trait的案例:Clone trait Clone是非对象安全的,所以不能作为trait对象。

 trait Clone{fn clone(&self) ->Self
}

因为clone()返回Self类型,不符合上面的规则(1)。所以尽管你对你实现Clone
trait的对象调用clone()方法,但是,你不能把&Clone带到任何的地方去。

3、关于trait与泛型,struct结合, 一个更进一步的例子

例子: 有一个Manager,Empylee,他们都共同实现Earn(赚钱的能力) trait。
里面有一个问题:当抽像变成具体时,可能在编译时无法确定对象大小。


pub trait Earn: Send + Sync {fn earn(&self);
}#[derive(Debug, Clone)]
struct Manager<T>
whereT: Earn,
{people: Vec<Box<T>>,
}trait Run {fn run(&self);
}
#[derive(Debug, Clone)]
struct Employee(i32);impl Earn for Employee {fn earn(&self) {}
}impl<T: Earn> Earn for Manager<T> {fn earn(&self) {}
}//
impl<T: Earn> Manager<T> {fn make_employees(&self) -> Vec<Box<dyn Earn>> {let mut v = Vec::new();let e = Employee(0);println!("e:{:?}", e);v.push(Box::new(e) as Box<dyn Earn>); // as Box<dyn Earn>);v}fn make_managers(&self) -> Vec<Box<dyn Earn>> {let mut v = Vec::new();{// problem :把抽像变具体let e = self.make_employees();let manager = Manager{ people: e };}// oklet e = Employee(0);let manager = Manager {people: vec![Box::new(e)],};v.push(Box::new(manager) as Box<dyn Earn>);v}
}
fn main() {// let t = Trade(0);// let v = t.to_vec();println!("ok");
}
关于trait更进一步的了解,可以参考,写得不错:https://zhuanlan.zhihu.com/p/127365605

4、一个有意思的库: DynClone
在github上,DynClone好象想做些不同的事。

https://github.com/dtolnay/dyn-clone

如:

use dyn_clone::DynClone;trait MyTrait: DynClone {fn recite(&self);
}impl MyTrait for String {fn recite(&self) {println!("{} ♫", self);}
}fn main() {let line = "The slithy structs did gyre and gimble the namespace";// Build a trait object holding a String.// This requires String to implement MyTrait and std::clone::Clone.let x: Box<dyn MyTrait> = Box::new(String::from(line));x.recite();// The type of x2 is a Box<dyn MyTrait> cloned from x.let x2 = dyn_clone::clone_box(&*x);x2.recite();
}

Rust : Trait Object safe 问题相关推荐

  1. Rust, Trait Object, Object Safty

    写了下面一段: async fn put<'a, S, E, F>(store: Arc<Mutex<dyn Storer<'a, dyn Stream<Item ...

  2. Rust Trait简介

    Rust trait简介 内容总结自<The Rust Programing Language> 首先简单说一下泛型:这个基础和C++的模板大概类似,从语法编译层面提供一种接收任意类型的手 ...

  3. rust - trait学习

    通过对<Rust 程序设计语言>,<通过例子学 Rust 中文版>以及令狐一冲老师对相关知识点的学习总结而成. rust - trait学习 1 trait 的基本含义 2 定 ...

  4. Rust ---- trait和mod的使用

    // lib.rs 文件内容pub mod shape {pub trait Area {fn calculate_area(&self) -> u32;}#[derive(Debug) ...

  5. rust原地复活_Rust语言的缺点

    经常看到Rust吹,好像一门语言能解决所有的问题,但事实上并不是这样.就好像刚开始对Haskell感兴趣是在网上看到Haskell简洁优雅的快排,但是传教士不会告诉你这不是原地排序,时间复杂度也有很大 ...

  6. [PaperNote] Confidential Computing Direction

    Confidential Computing方向论文的阅读笔记 文章目录 occlum occlum策略 libos 组成 安全性分析 实现 sgx 简介 Intel计算架构背景 SGX的安全性背景 ...

  7. rust为什么显示不了国服_捋捋 Rust 中的 impl Trait 和 dyn Trait

    缘起 一切都要从年末换工作碰上特殊时期, 在家闲着无聊又读了几首诗, 突然想写一个可以浏览和背诵诗词的 TUI 程序说起. 我选择了 Cursive 这个 Rust TUI 库. 在实现时有这么一个函 ...

  8. 【Rust投稿】捋捋 Rust 中的 impl Trait 和 dyn Trait

    本文来自 PrivateRookie 的知乎投稿:https://zhuanlan.zhihu.com/p/109990547 缘起 一切都要从年末换工作碰上特殊时期, 在家闲着无聊又读了几首诗, 突 ...

  9. Rust基础-关于trait之五

    基于上一篇Rust基础-关于trait之四-不得不说一下rust fat point 如果Trait之间有继承关系时,vtable 是什么布局呢? 如果看过上一篇,那么这张图应该能够看明白了. 所有的 ...

  10. Rust impl Trait和dyn Trait

    impl Trait:静态分发 dyn Trait:动态分发 静态分发:在编译期就确定了具体返回类型,函数只能返回一种类型. 动态分发:在运行时才能确定具体返回类型,函数可以返回多种类型. Trait ...

最新文章

  1. 'putText' is not a member of 'cv'
  2. matplotlib安装
  3. 浅谈高并发系统性能调优
  4. vim 安装_vim实战:插件安装(Vundle,NerdTree)
  5. python提供了两个对象身份比较操作符是_python 对象
  6. ThreadSanitizer检测工具-动态数据竞争检测技术
  7. android 8.0 图标规范,Android 8.0自适应图标
  8. Windows编程 从消息窗口到基本窗口 游戏循环窗口框架的简单实现
  9. apikey、apisecret在api请求中的使用
  10. 用html代码制作一个歌单,歌单.html · 李岢恩/MusicClub - Gitee.com
  11. 波长传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  12. table标签的介绍
  13. suspicious number
  14. SuSE and NLD9 user pls note
  15. windows7/10中Excel以单独进程窗口打开设置方法?
  16. firefox(火狐)与IE Chrome浏览器兼容的javascript和CSS写法
  17. rds mysql 视图 索引_数据库 视图 索引
  18. 华为od统一考试B卷【迷宫问题】Python 实现
  19. java计算机毕业设计养老院管理系统源码+数据库+系统+lw文档+部署
  20. MAC“相对于宗卷的格式项目太大无法拷贝”+“此电脑不能读取您插入的磁盘”解决

热门文章

  1. 【BZOJ】2194: 快速傅立叶之二
  2. DRBD安装编译后: modprobe drdb FATAL: Module drdb not found
  3. iOS pragma mark的用法
  4. 【通信基础知识】白噪声、相关解调和相干解调
  5. asp.net 事件调用事件问题?
  6. 关于母板页中runnat=server 窗体标记的问题
  7. 学习PetShop3.0(9)工厂的资料
  8. HTML5 新属性的讲解
  9. PyQt5-QLineEdit控件使用
  10. [android界面]android中src和background区别——前景与背景