Rust的运行时多态
创始人
2024-11-14 10:06:11
0

Rust的运行时多态

Rust的静态多态即编译时多态,通过**泛型+特征约束(Generic Type + Trait Constrait)**来实现;

那么动态多态(运行时多态)呢?答案是特征对象(Trait Object)

特征对象不是一个实例,而是一个结构体类型。

语法是dyn TraitName,编译时指示某个对象是实现TraitName的类型,其具体类型未知。

分析

程序运行时,要调用一个特征方法,需要两个要素:

  • 对象实例(对象类型未知,因此其编译期大小未知)
  • 特征的方法表

所以特征对象结构体必须获知以上两个要素。

发生运行时多态时,在编译阶段编译器无法辨别对象实例的类型,因此对象实例要素的大小无法获知,进而特征对象(Trait Object)的大小在编译阶段无法被确定,这决定了Trait Object只能存放在堆上,通过引用或智能指针来访问

指向特征对象的引用或智能指针,包含了两个指针成员,在程序运行时,ptr1在指向对象实例,ptr2指向该对象类型的Trait Method实现。

典型用例

 #[derive(Debug)] struct Journal {     author: String,     year: u16,     from: String, } #[derive(Debug)] struct Conference {     author: String,     year: u16,     country: String, }  trait Summary {     fn summary(&self) -> String; }  impl std::fmt::Debug for dyn Summary {     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {         write!(f, "{}", self.summary())     } }  impl Summary for Journal {     fn summary(&self) -> String {         format!("{}\t{}\t{}", self.author, self.year, self.from)     } } impl Summary for Conference {     fn summary(&self) -> String {         format!("{}\t{}\t{}", self.author, self.year, self.country)     } }  // can't defer concrete type in compile stage, trait constrain can't used here // fn init_default(_type: &str) -> impl Summary { //     if _type == "journal" { //         Journal { //             author: "hjd".to_owned(), //             year: 2018, //             from: "Nature".to_owned(), //         } //     } else { //         Conference { //             author: "hjd".to_owned(), //             year: 2018, //             country: "China".to_owned(), //         } //     } // }  // 只能使用特征对象进行动态分发,因为返回类型编译期无法推理获知 fn init_default(_type: &str) -> Box {     if _type == "journal" {         Box::new(Journal {             author: "hjd".to_owned(),             year: 2018,             from: "Nature".to_owned(),         })     } else {         Box::new(Conference {             author: "hjd".to_owned(),             year: 2018,             country: "China".to_owned(),         })     } }  fn main() {     let p1 = init_default("journal");     let p2 = init_default("conference");     let p3 = init_default("journal");     let p4 = init_default("conference");      let p_list = vec![p1, p2, p3, p4];     // dyn Summary是一个特征对象类型,它忘记了自己之前的具体类型,只能调用Summary特征中的方法     for p in p_list.iter() {         println!("{:?}", p);     } }   

相关内容

热门资讯

玩家攻略,牛牛房卡制作链接生肖... 您好!微信生肖系列/新大圣大厅链接获取房卡可以通过以下几种方式购买: 1.微信渠道:(生肖系列/新...
一分钟了解!牛牛房卡游戏平台加... 新荣耀/飞鹰互娱房卡更多详情添加微:33549083、 2、在商城页面中选择房卡选项。 ...
正版授权“在哪里买炸金花房卡哪... 炫酷大厅是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:44346008许多玩家在游戏中会购买房卡来...
重大通报,牛牛房卡怎么获得九哥... 重大通报,牛牛房卡怎么获得九哥联盟/微信链接房卡购买渠道九哥联盟是一款非常受欢迎的游戏,咨询房/卡添...
一分钟了解!微信金花房卡怎么弄... 您好!微信芝麻大厅大厅链接获取房卡可以通过以下几种方式购买: 1.微信渠道:(芝麻大厅)大厅介绍:...
秒懂教程“可以开房炸金花微信房... 新西游牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:86909166许多玩家在游戏中会购买房卡...
科技实测!游戏微信牛牛房卡玄武... 微信游戏中心:玄武大厅房卡在哪里买打开微信,添加客服微信【88355042】,进入游戏中心或相关小程...
ia攻略/牛牛房卡制作链接卡卡... 卡卡娱乐是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:【3329006910】或QQ:332900...
给大家讲解“金花房卡微信链接怎... 新全游牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:160470940许多玩家在游戏中会购买房...
推荐一款!金花房卡制作链接烛龙... 今 日消息,烛龙大厅房卡添加微信33549083 苹果今日发布了 iOS 16.1 正式版更新,简单...
头条推荐!牛牛房卡游戏平台加盟... 光明联盟是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:【3329006910】或QQ:332900...
一分钟了解!牛牛房卡游戏平台加... 您好!微信荣耀乐娱大厅链接获取房卡可以通过以下几种方式购买: 1.微信渠道:(荣耀乐娱)大厅介绍:...
正版授权“可以一起创房的牛牛,... 美猴王牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:160470940许多玩家在游戏中会购买房...
ia攻略/金花房卡专卖店新众亿... 今 日消息,新众亿/皇豪互娱房卡添加微信33549083 苹果今日发布了 iOS 16.1 正式版更...
重大通报,牛牛房卡制作链接战皇... 战皇大厅房卡更多详情添加微:33549083、 2、在商城页面中选择房卡选项。 3、根...
重大通报,牛牛房卡官网新大海/... 微信游戏中心:新大海房卡在哪里买打开微信,添加客服微信【88355042】,进入游戏中心或相关小程序...
头条推荐!金花房卡制作链接趣游... 趣游联盟是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:【3329006910】或QQ:332900...
ia攻略/牛牛房卡批发平台新老... 您好!微信新老夫子大厅链接获取房卡可以通过以下几种方式购买: 1.微信渠道:(新老夫子)大厅介绍:...
ia实测“怎样创建微信金花链接... 新西游牛牛是一款非常受欢迎的棋牌游戏,咨询房/卡添加微信:160470940许多玩家在游戏中会购买房...
一分钟了解!金花充值房卡火狐大... 火狐大厅/新超圣房卡更多详情添加微:33549083、 2、在商城页面中选择房卡选项。 ...