| 有的时间,可能希望利用的特质已经实现了其它特质(看背面可以知道,实际是要求相关类型实现了其它特质)。 RUST支持为特质(trait)指定限定的特质。
 例如我们定义特质A,之后定义了类型T,这个时间还希望T已经实现了特质TC。
 在rust中就是这个语法:
 trait tx:t1
 trait tx:t1+t2..+tn
 根据相关数据的例子和说明,必要特别注意,具体的实现都是依靠于类型,而不是特质。
 一、示例1
 
 在本例中Point必须实现特质Copy和Display和OutlinePrint,注意OutlinePrint的定义:复制代码use std::fmt;struct Point {    x: i32,    y: i32,}trait Copy{    fn copy(&self) -> Self;}trait OutlinePrint: fmt::Display+Copy{    fn outline_print(&self) {        let output = self.to_string();        let len = output.len();        println!("{}", "*".repeat(len + 4));        println!("*{}*", " ".repeat(len + 2));        println!("* {output} *");        println!("*{}*", " ".repeat(len + 2));        println!("{}", "*".repeat(len + 4));    }}impl OutlinePrint for Point {}impl fmt::Display for Point {    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {        write!(f, "({}, {})", self.x, self.y)    }}impl Copy for Point {    fn copy(&self) -> Self {            Point { x: self.x, y: self.y }    }}fn main() {    let p = Point { x: 10, y: 20 };    p.outline_print();    let c=p.copy();    c.outline_print();}
trait OutlinePrint: fmt:
  isplay+Copy 多个特质之间用+号毗连。
 输出如下:
 
 
 二、示例2-在方法中利用特质有关方法
 
 把以上的例子轻微修改下:
 本例中,起首为OutlinePrint增加一个限定Sized,其次方法outline_print是先copy再to_string.复制代码use std::fmt;struct Point {    x: i32,    y: i32,}trait Copyable {    fn copy(&self) -> Self;}trait OutlinePrint: fmt::Display + Copyable +Sized{    fn outline_print(&self) {        // 先创建副本        let copied = self.copy();        // 然后将副本转换为字符串        let output = copied.to_string();        let len = output.len();        println!("{}", "*".repeat(len + 4));        println!("*{}*", " ".repeat(len + 2));        println!("* {} *", output);        println!("*{}*", " ".repeat(len + 2));        println!("{}", "*".repeat(len + 4));    }}impl OutlinePrint for Point {}impl fmt::Display for Point {    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {        write!(f, "({}, {})", self.x, self.y)    }}impl Copyable for Point {    fn copy(&self) -> Self {            Point { x: self.x, y: self.y }    }}fn main() {    let p = Point { x: 10, y: 20 };    p.outline_print();}
如果OutlinePrint不添加一个Sized,那么会提示语句 let copied=self.copy()报错:doesn't have a size known at compile-time
 rustc的给出的建议是:fn outline_print(&self) where Self: Sized  ,即为方法outline_print的参数添加限定(这是我们习惯的方式)
 为什么Point不必要实现Sized?这是因为Point的巨细是确定的,其次编译器会为此类类型隐式实现。
 输出略。
 三、示例3-如果不利用特质的限定
 
 由于可以为方法的参数举行限定,我们很轻易想到其实可以只对参数限定即可。
 为了节约篇幅,这里只把核心的内容贴出:
 输出:复制代码trait OutlinePrint{    fn outline_print(&self)    where Self: fmt::Display + Copyable+Sized     {        // 先创建副本        let copied = self.copy();        // 然后将副本转换为字符串        let output = copied.to_string();        let len = output.len();        println!("{}", "*".repeat(len + 4));        println!("*{}*", " ".repeat(len + 2));        println!("* {} *", output);        println!("*{}*", " ".repeat(len + 2));        println!("{}", "*".repeat(len + 4));    }}
 四、小结
 
 这种定义方式个人认为不是很符合一般思维方式,这是因为明明是对类型的限制,但是这种限制确写在特质上。
 例如在java等语言中,就没有这种方式。
 个人更加倾向于采用示例3的方式,尤其是在打仗多了雷同JAVA之类的OOP语言后。
 
 固然rust这种定义方式也有长处:如果相关特质方法的参数都是这种要求,那么写在特质上,的确会少打一些字。
 以是,rust程序员可以根据必要来决定限定方式,某种水平上rust为我们提供了方便性和灵活性。
 
 
 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
 |