网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > Rust >

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

时间:2025-04-03 17:03

人气:

作者:admin

标签:

导读:回忆下孤儿规则: 1.只有当一个trait或类型在当前的crate中定义时,才能为外部类型实现该trait。 没有限定是特质还是类型 反过来,如果特质和类型都是外部,那么不能在当前单元包实现...

回忆下孤儿规则:

1.只有当一个trait或类型在当前的crate中定义时,才能为外部类型实现该trait。 没有限定是特质还是类型

反过来,如果特质和类型都是外部,那么不能在当前单元包实现

2.例外情况-std中特质是例外。大体验证了凡事都有例外

孤儿规则的目的:避免编译器无法确定应该用哪一个实现。

这个目的很容易理解。无论是否叫孤儿,绝大部分语言中都是类似的规则-不允许一个类型实现接口/特质的时候,有多处不一样代码。

 

书本上主要讨论如何绕过孤儿规则,方案就是:对外部类型进行封装,构建一个新的本地类型,然后就可以实现本地类型的外部特质,从而间接实现外部类型的外部特质。

不过这本质上是一种绕过问题的解决方案,在有些场合中也可以将就使用。在rust中有提到相对直接的解决方法,不过本文暂不论述。

一、孤儿规则示例

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

其中wsmain是二进制单元,对于wsmain而言,student和teacher两个都是外部crate,看wsmain的Cargo.toml就明白了:

[package]
name = "wsmain"
version.workspace=true
edition.workspace=true

[dependencies]
student={path="../student"}
teacher={path="../teacher"}

本例中分别在teacher包中定义了特质Print,并在wsmain中尝试为Teacherinfo(teacher中的struct)实现Print,为了节省篇幅,放在一起:

//在teacher包
pub trait Print{
    fn print(&self);
}
pub struct Teacherinfo{
    pub name: String,
    pub age: u8,
    pub gender: String,
    pub position: String
}
//在wsmain二进制单元包中
impl Print for Teacherinfo{
    fn print(&self){
        println!("{}",self.name);
    }
}

如果你尝试运行,那么回得到如下提示:

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

何谓包装类,此处不介绍,直接看示例代码:

use student::*;
use teacher::*;

fn main() {
    let lml = Studentinfo {
        name: String::from("lml"),
        age: 18,
        gender: String::from("女"),
        no: String::from("12101"),
    };
    print_student(&lml);
    lml.learn();
    lml.sleep();

    let lu = Teacherinfo {
        name: String::from("lu"),
        age: 46,
        gender: String::from("男"),
        position: String::from("教研组长"),
    };
    lu.teach_student(&lml);
    print_teacher(&lu);
    let _me = Box::new(String::from("中国"));

    let my_lu = MyTeacherinfo(lu);
    my_lu.print();
}

struct MyTeacherinfo(Teacherinfo);
impl Print for MyTeacherinfo {
    fn print(&self) {
        println!(
            "教师基本信息-姓名:{},年龄:{},性别:{},职位:{}",
            self.0.name, self.0.age, self.0.gender, self.0.position
        );
    }
}

在这个示例中,定义了一个新的结构,成员只包含一个Teacherinfo。用的是使用元组定义结构的方式。

看运行结果:

三、小结

这种利用包装模式绕过的方法有时候也能起到作用,只不过,我更愿意听到直面问题的方案。

利用包装模式是rust直常常提到的newtype模式的一种。所谓newtype,大概可以这样理解:基于特定构建一个新的类型,这样可以绕过一些问题,达成一些目的。

用包装器来绕过,还是有些小麻烦,倒也不是不能用!

 

本文来自博客园,作者:正在战斗中,转载请注明原文链接:https://www.cnblogs.com/lzfhope/p/18807962

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信