rust学习二十.9、RUST绕过孤儿规则实现特质和包装器缺点 ...

打印 上一主题 下一主题

主题 1727|帖子 1727|积分 5181

回想下孤儿规则:
1.只有当一个trait或范例在当前的crate中界说时,才能为外部范例实现该trait。 没有限定是特质还是范例
反过来,如果特质和范例都是外部,那么不能在当前单位包实现
2.例外情况-std中特质是例外。大体验证了凡事都有例外
孤儿规则的目的:避免编译器无法确定应该用哪一个实现。
这个目的很容易理解。无论是否叫孤儿,绝大部分语言中都是类似的规则-不允许一个范例实现接口/特质的时候,有多处不一样代码。
 
书本上主要讨论怎样绕过孤儿规则,方案就是:对外部范例进行封装,构建一个新的本地范例,然后就可以实现本地范例的外部特质,从而间接实现外部范例的外部特质。
不外这本质上是一种绕干涉题的办理方案,在有些场合中也可以将就使用。在rust中有提到相对直接的办理方法,不外本文暂不叙述。
一、孤儿规则示例

如下图,这是一个包含了三个单位的工作空间:

其中wsmain是二进制单位,对于wsmain而言,student和teacher两个都是外部crate,看wsmain的Cargo.toml就明确了:
  1. [package]
  2. name = "wsmain"
  3. version.workspace=true
  4. edition.workspace=true
  5. [dependencies]
  6. student={path="../student"}
  7. teacher={path="../teacher"}
复制代码
本例中分别在teacher包中界说了特质Print,并在wsmain中实验为Teacherinfo(teacher中的struct)实现Print,为了节省篇幅,放在一起:
  1. //在teacher包
  2. pub trait Print{
  3.     fn print(&self);
  4. }
  5. pub struct Teacherinfo{
  6.     pub name: String,
  7.     pub age: u8,
  8.     pub gender: String,
  9.     pub position: String
  10. }
  11. //在wsmain二进制单元包中
  12. impl Print for Teacherinfo{
  13.     fn print(&self){
  14.         println!("{}",self.name);
  15.     }
  16. }
复制代码
如果你实验运行,那么回得到如下提示:

二、用包装类绕过孤儿规则

何谓包装类,此处不介绍,直接看示例代码:
  1. use student::*;
  2. use teacher::*;
  3. fn main() {
  4.     let lml = Studentinfo {
  5.         name: String::from("lml"),
  6.         age: 18,
  7.         gender: String::from("女"),
  8.         no: String::from("12101"),
  9.     };
  10.     print_student(&lml);
  11.     lml.learn();
  12.     lml.sleep();
  13.     let lu = Teacherinfo {
  14.         name: String::from("lu"),
  15.         age: 46,
  16.         gender: String::from("男"),
  17.         position: String::from("教研组长"),
  18.     };
  19.     lu.teach_student(&lml);
  20.     print_teacher(&lu);
  21.     let _me = Box::new(String::from("中国"));
  22.     let my_lu = MyTeacherinfo(lu);
  23.     my_lu.print();
  24. }
  25. struct MyTeacherinfo(Teacherinfo);
  26. impl Print for MyTeacherinfo {
  27.     fn print(&self) {
  28.         println!(
  29.             "教师基本信息-姓名:{},年龄:{},性别:{},职位:{}",
  30.             self.0.name, self.0.age, self.0.gender, self.0.position
  31.         );
  32.     }
  33. }
复制代码
在这个示例中,界说了一个新的结构,成员只包含一个Teacherinfo。用的是使用元组界说结构的方式。
看运行效果:

三、小结

这种利用包装模式绕过的方法有时候也能起到作用,只不外,我更乐意听到直面题目的方案。
利用包装模式是rust直常常提到的newtype模式的一种。所谓newtype,大概可以这样理解:基于特定构建一个新的范例,这样可以绕过一些题目,达成一些目的。
用包装器来绕过,还是有些小麻烦,倒也不是不能用!
 

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

本帖子中包含更多资源

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

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

惊落一身雪

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