当前位置: 首页 > news >正文

武汉洪山区做网站的公司中国搜索引擎排行榜

武汉洪山区做网站的公司,中国搜索引擎排行榜,个人做负面网站犯法不,临清网站制作在拥有继承的语言中,可以定义一个名为shape的基类,该类上有一个draw方法。其他的类比如Button、SelectBox继承shape。它们各自覆盖draw方法。调用这些子类的draw方法时,就可以把它们统一当作shape来使用。不过Rust并没有继承,如果…

在拥有继承的语言中,可以定义一个名为shape的基类,该类上有一个draw方法。其他的类比如Button、SelectBox继承shape。它们各自覆盖draw方法。调用这些子类的draw方法时,就可以把它们统一当作shape来使用。不过Rust并没有继承,如果想做到这点,就得另寻出路。这个出路就是使用trait对象。trait对象的作用类似基类。

一、定义trait对象

(一)语法格式
trait对象是一种类型,定义语法如下

dyn 约束

约束是trait约束或者生存期约束。可以有多个约束,多个约束之间用+连接。
例如

dyn X
dyn X + Send
dyn X + Send + Sync
dyn X + 'static
dyn X + Send + 'static

X是一个trait

二、使用trait对象

trait对象是动态尺寸类型。像所有的 DST 一样,使用trait对象,必须使用它的指针类型;例如 &dyn SomeTraitBox<dyn SomeTrait>。trait对象的指针包括:
一个指向实现SomeTrait的类型T的实例的指针
一个指向虚拟方法表的指针。虚拟方法表也通常被称为虚函数表,它包含了T实现的SomeTrait的所有方法,T实现的SomeTrait的父trait 的每个方法,还有指向T的实现的指针。

例子

pub trait Draw {fn draw(&self);
}
pub struct Screen {pub shapes: Vec<Box<dyn Draw>>,     //存放trait对象的vector。Box<dyn Draw>就是trait对象,它指向一个实现了Draw的类型的实例
}impl Screen {pub fn run(&self) {for shape in self.shapes.iter() {shape.draw();     //在每个shape上调用draw方法}}
}
pub struct Button {pub width: u32,pub height: u32,pub label: String,
}
impl Draw for Button {fn draw(&self) {// 实际绘制按钮的代码}
}
struct SelectBox {width: u32,height: u32,options: Vec<String>,
}
impl Draw for SelectBox {fn draw(&self) {// code to actually draw a select box}
}
fn main() {let screen = Screen {shapes: vec![Box::new(SelectBox {width: 75,height: 10,options: vec![String::from("Yes"),String::from("Maybe"),String::from("No")],}),Box::new(Button {width: 50,height: 10,label: String::from("OK"),}),],};screen.run();
}

从上面代码中可以看出,是不是与基类指针很类似?

run并不检查元素是Button或者SelectBox的实例。如果实例没有实现trait对象所需的trait则编译错误
例如,

fn main() {let screen = Screen {shapes: vec![Box::new(String::from("Hi")),],};screen.run();
}

这个编译错误,因为String没有实现Draw

三、trait对象与泛型的区别

trait对象与带有trait约束的泛型结构体类似,但是也有不同。泛型参数一次只能替代一个具体类型,而trait对象则允许在运行时替代多种具体类型。
例如

pub struct Screen<T: Draw> {pub shapes: Vec<T>,
}
impl<T> Screen<T>
where T: Draw {pub fn run(&self) {for shape in self.shapes.iter() {shape.draw();}}
}

shapes是一个全是Button类型或者全是SelectBox类型的列表。总之,所有元素类型是相同的。
而使用trait对象,shapes能同时包含Box<Button>Box<SelectBox>,各个元素类型可以不同。

四、trait对象要求对象安全

只有对象安全的trait才可以组成trait对象。如果一个trait中所有的方法有如下属性时,则该trait是对象安全的:
1.返回值类型不为Self
2.方法没有任何泛型参数
Self代表自身。对象安全对于trait对象是必须的,因为一旦有了trait对象,就不再知晓实现该trait的具体类型是什么了。如果trait方法返回具体的Self类型,但是trait对象忘记了其真正的类型,那么方法不可能使用已经忘却的原始具体类型。同理对于泛型类型参数来说,当使用trait时其会放入具体的类型参数:此具体类型变成了实现该trait的类型的一部分。当使用trait对象时其具体类型被抹去了,故无从得知放入泛型参数类型的类型是什么。
一个trait的方法不是对象安全的例子是标准库中的Clone trait。

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

String实现了Clone trait,当在String实例上调用clone方法时会得到一个String实例。类似的,当调用Vec<T> 实例的clone方法会得到一个Vec<T> 实例。clone的签名需要知道什么类型会代替Self,因为这是它的返回值。
如果尝试做一些违反对象安全规则的事情,编译器会提示你。
例如,

pub struct Screen {pub components: Vec<Box<dyn Clone>>,
}

将会得到如下错误:
error[E0038]: the trait std::clone::Clone cannot be made into an object
Clone不能组成trait对象。

http://www.ds6.com.cn/news/59886.html

相关文章:

  • 合肥做公司网站b2b平台推广网站
  • 企业网站建设优势营销托管全网营销推广
  • 南京开发seo软文推广
  • WordPress建站 网盘视频升华网络推广软件
  • 宁夏网站建设怎么样百度网站推广教程
  • 湖州市建设中心网站2022重大时政热点事件简短
  • 杭州做网站软件利用搜索引擎营销成功的案例
  • 网站开发调用别人网站的组件seo排名软件怎么做
  • 浦元品牌网站建设免费建站哪个最好
  • 免费做app和网站的平台有哪些搜索广告和信息流广告区别
  • 做房地产一级市场的看什么网站互联网营销的方法
  • html中文美食网站培训体系搭建
  • 东莞网站建设.com上海网络营销seo
  • 电大企业网站建设论文范文如何优化seo关键词
  • 电子商务网站有那些功能网站开发建设步骤
  • 佛山网站建设定制沈阳seo优化排名公司
  • 南平住房和城乡建设部网站网络策划营销
  • 营销型网站建设方面的书企业网站建设步骤
  • 做网站有那几种末班网页设计与制作作业成品
  • wordpress次级菜单seo网站是什么意思
  • 大型门户网站 要求下拉框关键词软件
  • 化工企业网站模板郑州网站推广技术
  • 网页设计代码解释河北seo技术培训
  • 建立网站的链接结构有哪几种形式简述其各自的优缺点拓客团队怎么联系
  • ftp网站上传成功后怎么做国际新闻稿件
  • 网站的建设可以起到什么作用关键词调词平台
  • by网站现在的域名百度网站优化软件
  • 网站搭建素材宁德市人民医院
  • 作文网站网址淮北seo
  • 网站管理员怎么联系网站查询域名入口