rust学习二十.8、RUST特质的限定,实为对类型的限定

打印 上一主题 下一主题

主题 1808|帖子 1808|积分 5424

有的时间,可能希望利用的特质已经实现了其它特质(看背面可以知道,实际是要求相关类型实现了其它特质)。
RUST支持为特质(trait)指定限定的特质。
例如我们定义特质A,之后定义了类型T,这个时间还希望T已经实现了特质TC
在rust中就是这个语法:
trait tx:t1
trait tx:t1+t2..+tn
根据相关数据的例子和说明,必要特别注意,具体的实现都是依靠于类型,而不是特质。
一、示例1
  1. use std::fmt;
  2. struct Point {
  3.     x: i32,
  4.     y: i32,
  5. }
  6. trait Copy{
  7.     fn copy(&self) -> Self;
  8. }
  9. trait OutlinePrint: fmt::Display+Copy{
  10.     fn outline_print(&self) {
  11.         let output = self.to_string();
  12.         let len = output.len();
  13.         println!("{}", "*".repeat(len + 4));
  14.         println!("*{}*", " ".repeat(len + 2));
  15.         println!("* {output} *");
  16.         println!("*{}*", " ".repeat(len + 2));
  17.         println!("{}", "*".repeat(len + 4));
  18.     }
  19. }
  20. impl OutlinePrint for Point {}
  21. impl fmt::Display for Point {
  22.     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  23.         write!(f, "({}, {})", self.x, self.y)
  24.     }
  25. }
  26. impl Copy for Point {
  27.     fn copy(&self) -> Self {
  28.             Point { x: self.x, y: self.y }
  29.     }
  30. }
  31. fn main() {
  32.     let p = Point { x: 10, y: 20 };
  33.     p.outline_print();
  34.     let c=p.copy();
  35.     c.outline_print();
  36. }
复制代码
在本例中Point必须实现特质Copy和Display和OutlinePrint,注意OutlinePrint的定义:
trait OutlinePrint: fmt:isplay+Copy
多个特质之间用+号毗连。
输出如下:

 
二、示例2-在方法中利用特质有关方法

把以上的例子轻微修改下:
  1. use std::fmt;
  2. struct Point {
  3.     x: i32,
  4.     y: i32,
  5. }
  6. trait Copyable {
  7.     fn copy(&self) -> Self;
  8. }
  9. trait OutlinePrint: fmt::Display + Copyable +Sized{
  10.     fn outline_print(&self) {
  11.         // 先创建副本
  12.         let copied = self.copy();
  13.         // 然后将副本转换为字符串
  14.         let output = copied.to_string();
  15.         let len = output.len();
  16.         println!("{}", "*".repeat(len + 4));
  17.         println!("*{}*", " ".repeat(len + 2));
  18.         println!("* {} *", output);
  19.         println!("*{}*", " ".repeat(len + 2));
  20.         println!("{}", "*".repeat(len + 4));
  21.     }
  22. }
  23. impl OutlinePrint for Point {}
  24. impl fmt::Display for Point {
  25.     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  26.         write!(f, "({}, {})", self.x, self.y)
  27.     }
  28. }
  29. impl Copyable for Point {
  30.     fn copy(&self) -> Self {
  31.             Point { x: self.x, y: self.y }
  32.     }
  33. }
  34. fn main() {
  35.     let p = Point { x: 10, y: 20 };
  36.     p.outline_print();
  37. }
复制代码
本例中,起首为OutlinePrint增加一个限定Sized,其次方法outline_print是先copy再to_string.
如果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-如果不利用特质的限定

由于可以为方法的参数举行限定,我们很轻易想到其实可以只对参数限定即可。
为了节约篇幅,这里只把核心的内容贴出:
  1. trait OutlinePrint{
  2.     fn outline_print(&self)
  3.     where Self: fmt::Display + Copyable+Sized
  4.      {
  5.         // 先创建副本
  6.         let copied = self.copy();
  7.         // 然后将副本转换为字符串
  8.         let output = copied.to_string();
  9.         let len = output.len();
  10.         println!("{}", "*".repeat(len + 4));
  11.         println!("*{}*", " ".repeat(len + 2));
  12.         println!("* {} *", output);
  13.         println!("*{}*", " ".repeat(len + 2));
  14.         println!("{}", "*".repeat(len + 4));
  15.     }
  16. }
复制代码
输出:

四、小结

这种定义方式个人认为不是很符合一般思维方式,这是因为明明是对类型的限制,但是这种限制确写在特质上。
例如在java等语言中,就没有这种方式。
个人更加倾向于采用示例3的方式,尤其是在打仗多了雷同JAVA之类的OOP语言后。
 
固然rust这种定义方式也有长处:如果相关特质方法的参数都是这种要求,那么写在特质上,的确会少打一些字。
以是,rust程序员可以根据必要来决定限定方式,某种水平上rust为我们提供了方便性和灵活性。
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

雁过留声

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表