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

深圳服务网站建设如何从建设局网站上更换职称人员

深圳服务网站建设,如何从建设局网站上更换职称人员,一级站点和二级站点区别,视频模板免费下载网站特征(Trait) 特征#xff08;trait#xff09;是rust中的概念#xff0c;类似于其他语言中的接口#xff08;interface#xff09;。在之前的代码中#xff0c;我们也多次见过特征的使用#xff0c;例如 #[derive(Debug)]#xff0c;它在我们定义的类型(struct)上自动…特征(Trait) 特征trait是rust中的概念类似于其他语言中的接口interface。在之前的代码中我们也多次见过特征的使用例如 #[derive(Debug)]它在我们定义的类型(struct)上自动派生 Debug 特征接着可以使用 println!({:?}, x) 打印这个类型。 特征定义了一个可以被共享的行为只要实现了特征你就能使用该行为。 定义特征 如果不同的类型具有相同的行为那么我们就可以定义一个特征然后为这些类型实现该特征。定义特征是把一些方法组合在一起目的是定义一个实现某些目标所必需的行为的集合。 例如我们现在有圆形和长方形两个结构体它们都可以拥有周长面积。因此我们可以定义被共享的行为只要实现了特征就可以使用。 pub trait Figure { // 为几何图形定义名为Figure的特征fn girth(self) - u64; // 计算周长fn area(self) - u64; // 计算面积 }这里使用 trait 关键字来声明一个特征Figure 是特征名。在大括号中定义了该特征的所有方法在这个例子中有两个方法分别是fn girth(self) - u64;和fn area(self) - u64;特征只定义行为看起来是什么样的而不定义行为具体是怎么样的。因此我们只定义特征方法的签名而不进行实现此时方法签名结尾是 ;而不是一个 {}。 接下来每一个实现这个特征的类型都需要具体实现该特征的相应方法编译器也会确保任何实现 Figure 特征的类型都拥有与fn girth(self) - u64;和fn area(self) - u64;签名的定义完全一致的方法。 熟悉C的同学看到这里会觉得trait和C的纯虚函数非常类似而熟悉go语言的同学看到这里会觉得和go语言的interface非常类似。 实现特征 上面声明了特征但是它只包含了一个函数声明而没有实现。接下来要为具体的类型实现特征。 use std::f64::consts::PI;trait Figure { // 为几何图形定义名为Figure的特征fn girth(self) - f64; // 计算周长fn area(self) - f64; // 计算面积 } struct Rectangle{x:f64,y:f64, }struct Circle{r:f64, }impl Rectangle {// 为Rectangle实现构造方法fn new(x:f64, y:f64) - Self{ Rectangle { x, y }} }impl Circle {// 为Circle实现构造方法fn new(r:f64) - Self{Circle { r }} }impl Figure for Rectangle {fn area(self) - f64 {self.x * self.y}fn girth(self) - f64 {2.0 * (self.x self.y)} }impl Figure for Circle{fn area(self) - f64 {2.0 * PI * self.r}fn girth(self) - f64 {PI * self.r.powi(2i32)} }fn main() {let rec Rectangle::new(1.0, 2.0);let cir Circle::new(3.0);println!(长方形的周长是{}面积是{},rec.girth(), rec.area());println!(圆形的周长是{}面积是{}, cir.girth(), cir.area()); }impl Figure for Circle意为“为 Circle 类型实现 Figure 特征”然后在 impl 中实现该特征的具体方法。这种将接口分离出来的做法有别于传统面向对象的语言例如C。这种做法是组合优于继承的一种体现。 这段代码执行结果如下所示 长方形的周长是6面积是2 圆形的周长是28.274333882308138面积是18.84955592153876特征定义与实现的位置(孤儿规则) 如果想让别人使用我们的特征那么需要将特征和对应的类型定义为pub例如 pub trait Figure { // 为几何图形定义名为Figure的特征fn girth(self) - f64; // 计算周长fn area(self) - f64; // 计算面积 } pub struct Rectangle{pub x:f64,pub y:f64, }pub struct Circle{pub r:f64, }关于特征实现与定义的位置有一条非常重要的原则如果你想要为类型 A 实现特征 T那么 A 或者 T 至少有一个是在当前作用域中定义的 但是你无法在当前作用域中为 String 类型实现 Display 特征因为它们俩都定义在标准库中其定义所在的位置都不在当前作用域跟你半毛钱关系都没有看看就行了。该规则被称为孤儿规则可以确保其它人编写的代码不会破坏你的代码也确保了你不会莫名其妙就破坏了风马牛不相及的代码。 特征的默认实现 你可以在特征中定义具有默认实现的方法这样其它类型无需再实现该方法或者也可以选择重载该方法。这和C的虚函数类似允许方法有实现而不仅仅是声明。例如: pub struct Dog; pub struct Cat;pub trait Animal {fn run(self) {println!(跑跑跑);} }impl Animal for Dog { // 为Dog实现特征Animal}impl Animal for Cat { // 为Cat实现特征Animalfn run(self) {println!(猫在跑);} }fn main() {let cat Cat;let dog Dog;dog.run();cat.run(); }程序执行结果: 跑跑跑 猫在跑在特征中定义具有默认实现的方法这样其它类型无需再实现该方法或者也可以选择重载该方法。Dog类型使用默认的run方法而Cat类型选择重载了run方法。 默认实现允许调用相同特征中的其他方法哪怕这些方法没有默认实现。如此特征可以提供很多有用的功能而只需要实现指定的一小部分内容。例如 pub struct Dog; pub struct Cat;pub trait Animal {fn run(self) {println!(跑跑跑);}fn eat(self);fn sleep(self);fn every_daya(self) {self.eat();self.sleep();} }impl Animal for Dog { // 为Dog实现特征Animalfn eat(self) {println!(狗需吃狗粮);}fn sleep(self) {println!(狗在睡觉);} }impl Animal for Cat { // 为Cat实现特征Animalfn run(self) {println!(猫在跑);}fn eat(self) {println!(猫咪需要吃猫粮);}fn sleep(self) {println!(猫咪白天在睡觉);} }fn main() {let cat Cat;let dog Dog;dog.run();cat.run();dog.every_daya();cat.every_daya(); }我们给Animal特征加上了sleepeat以及every_day这三个方法。其中every_day方法我们做了实现。而sleep方法和eat方法没有在特征中做默认实现但是这不影响我们在every_day方法中调用它们。我们分别为Cat和Dog类型实现了eat方法和sleep方法。 这和C的虚基类非常类似在C中我们需要做的是在派生类中实现纯虚函数或者重载虚函数这里用的手段是继承。而在rust里可以由特征来实现。 使用特征作为函数参数 特征如果仅仅是用来实现方法那真的有些大材小用现在我们来讲下真正可以让特征大放光彩的地方。 现在先定义一个函数使用特征作为函数参数 pub fn notify(item: impl Animal) {println!({}, item.run()); }impl Animal它的意思是 实现了Animal特征 的 item 参数。你可以使用任何实现了 Summary 特征的类型作为该函数的参数同时在函数体内还可以调用该特征的方法。例如可以传递 Cat 或 Dog 的实例来作为参数而其它类型如 String 或者 i32 的类型则不能用做该函数的参数因为它们没有实现 Animal 特征。 特征约束(trait bound) 虽然 impl Trait 这种语法非常好理解但是实际上它只是一个语法糖在泛型中如下所示 pub fn astT: Summary(item: T) {println!({}, item.a()); }T: Summary 被称为特征约束它能够做的对类型进行约束。例如上面的notify函数的参数只要实现了Animal特征即可那么意味着我们可以传递Dog或者Cat的实例对象。如果我们有下面这样的函数。 fn func(a:impl Animal, b:impl Animal){// todo }想要函数的两个参数是同一种类型而不仅仅是实现了Animal特征即可。此时就需要使用特征约束。 fn funcT: Animal(a:T, b:T){// todo }像这样的方式就说明了泛型类型T必须实现Animal特征且a和b必须是同一种类型。 多重约束 除了单个约束条件我们还可以指定多个约束条件例如除了让参数实现 Animal 特征外还可以让参数实现 Display 特征以控制它的格式化输出 pub fn func(item: (impl Animal Display)) {}当然了在泛型中使用如下的形式 pub fn funcT: Animal Display(item: T) {}Where约束 当特征约束变得很多时函数的签名将变得很复杂 fn some_functionT: Display Clone, U: Clone Debug(t: T, u: U) - i32 {}通过 where约束可以将其变成下面的形式。 fn some_functionT, U(t: T, u: U) - i32where T: Display Clone,U: Clone Debug {}使用特征约束有条件地实现方法或特征 特征约束可以让我们在指定类型 指定特征的条件下去实现方法例如 #![allow(unused)] fn main() { use std::fmt::Display;struct PairT {x: T,y: T, }implT PairT {fn new(x: T, y: T) - Self {Self {x,y,}} }implT: Display PartialOrd PairT {fn cmp_display(self) {if self.x self.y {println!(The largest member is x {}, self.x);} else {println!(The largest member is y {}, self.y);}} } }cmp_display 方法并不是所有的 Pair 结构体对象都可以拥有只有 T 同时实现了 Display PartialOrd 的 Pair 才可以拥有此方法。 该函数可读性会更好因为泛型参数、参数、返回值都在一起可以快速的阅读同时每个泛型参数的特征也在新的代码行中通过特征约束进行了约束。 也可以有条件地实现特征, 例如标准库为任何实现了 Display 特征的类型实现了 ToString 特征 implT: Display ToString for T {// --snip-- }函数返回impl Trait fn return_run() - impl Animal {Cat }Cat实现了Animal特征因此可以用Cat对象的实例作为返回值。要注意的是虽然我们知道这里是一个 Cat 类型但是对于 return_run 的调用者而言他只知道返回了一个实现了 Animal 特征的对象但是并不知道返回了一个 Cat 类型。 这种 impl Trait 形式的返回值在一种场景下非常非常有用那就是返回的真实类型非常复杂你不知道该怎么声明时(毕竟 Rust 要求你必须标出所有的类型)此时就可以用 impl Trait 的方式简单返回。 通过 derive 派生特征 形如 #[derive(Debug)] 的代码已经出现了很多次这种是一种特征派生语法被 derive 标记的对象会自动实现对应的默认特征代码继承相应的功能。 例如 Debug 特征它有一套自动实现的默认代码当你给一个结构体标记后就可以使用 println!(“{:?}”, s) 的形式打印该结构体的对象。 再如 Copy 特征它也有一套自动实现的默认代码当标记到一个类型上时可以让这个类型自动实现 Copy 特征进而可以调用 copy 方法进行自我复制。 总之derive 派生出来的是 Rust 默认给我们提供的特征在开发过程中极大的简化了自己手动实现相应特征的需求当然如果你有特殊的需求还可以自己手动重载该实现。 调用方法需要引入特征 如果你要使用一个特征的方法那么你需要将该特征引入当前的作用域中。后续在包和模块中我们来演示该部分。 参考资料 Rust语言圣经
http://www.w-s-a.com/news/49598/

相关文章:

  • 南昌网站建设模板服务商建设什么网站挣钱
  • 网站建设实训记录企业网站建设运营
  • 视频网站文案住房和城乡建设部门
  • 汕头网站排名推广新余门户网站开发
  • 湖南智能网站建设哪家好wordpressμ
  • 公司网站备案必须是企业信息么睢宁县凌城做网站的
  • 上海网站建设公司 珍岛宁波免费自助建站模板
  • 南昌知名的网站建设公司南京网站开发选南京乐识赞
  • 外贸网站建设 深圳seo怎么提升关键词的排名
  • 网站推广效果的评价google关键词
  • 模板网站建站哪家好做微信充值网站
  • 抽奖的网站怎么做的广州小程序定制开发
  • 网站的文件夹建设企业网站公积金
  • 做网站的的价位网站建设 考试题目
  • 深圳比邻网站建设北京优化服务
  • 菏泽网站建设哪家好电子商务网络安全
  • 仿一个网站广州网站建设正规公司
  • 网站建设 目的seo网站关键词排名快速
  • 什么叫做响应式网站自媒体全平台发布
  • 企业网站 案例哪里需要人做钓鱼网站
  • 厚街东莞网站建设网站开发者调试模式
  • 网站推广营销联系方式wordpress adminlte
  • 哪些网站可以做文字链广告卖水果网站建设的策划书
  • 雕刻业务网站怎么做企业qq官网
  • 新华书店的做的数字阅读网站wordpress编辑器格式
  • jq做6个网站做什么好广西临桂建设局网站
  • 网站新闻图片尺寸南京网站设计公司
  • 重庆seo建站网站服务器 安全
  • 咸宁做网站的公司桂林网站建设兼职
  • 教做网站网站开发行业分析