rust 面向对象、trait

2023-12-17

目录

1,结构体、成员方法

2,trait(特征)

3,同名函数的覆盖、冲突

4,trait继承

5,trait的孤儿规则

6,trait的type成员


给结构体添加方法有2种,一种是直接实现,一种的带trait的实现。

直接实现的方式中,数据和方法是对应的。带trait的实现中,trait是一组可以被共享的行为,只要实现了特征,你就能使用这组行为。

1,结构体、成员方法


struct SearchData{
    
}
impl SearchData{
    fn f(&self)-> i32{
        return 123;
    }
    fn f2()-> i32{
        return 456;
    }
}


fn main() {
    let x=SearchData{};
    assert_eq!(x.f(), 123);
    assert_eq!(SearchData::f2(), 456);
}

2,trait(特征)

带trait的实现方式中,数据、接口描述、接口实现要分开。

trait Solution{
    fn find(&self)-> i32;
}
struct SearchData{
    
}
impl Solution for SearchData{
    fn find(&self)-> i32{
        return 123;
    }
}
fn main() {
    let x=SearchData{};
    println!("{}",x.find());
}

3,同名函数的覆盖、冲突

直接实现的方法会覆盖trait中的方法

struct SearchData{
    
}
impl SearchData{
    fn f1(&self)-> i32{
        return 100;
    }
    fn f2(&self)-> i32{
        return 222;
    }
}
trait S{
    fn f1(&self)-> i32;
    fn f3(&self)-> i32;
}

impl S for SearchData{
    fn f1(&self)-> i32{
        return 111;
    }
    fn f3(&self)-> i32{
        return 333;
    }
}

fn main() {
    let x=SearchData{};
    println!("{} {} {}",x.f1(),x.f2(),x.f3());
}

输出:100 222 333

也就是说,代码可以正常运行,类型中非函数会覆盖trait中的同名函数。

被覆盖的函数也不是完全无法调用,只是不能用最简单的写法去调用,调用方法:

struct SearchData{
    
}
impl SearchData{
    fn f1(&self)-> i32{
        return 100;
    }
    fn f2()->i32{
        return 222;
    }
}
trait S{
    fn f1(&self)-> i32;
    fn f2()->i32;
}

impl S for SearchData{
    fn f1(&self)-> i32{
        return 111;
    }
    fn f2()->i32{
        return 333;
    }
}

fn main() {
    let x=SearchData{};
    println!("{} {}",x.f1(),S::f1(&x));
    println!("{} {}",SearchData::f2(),<SearchData as S>::f2());
}

带self参数的,用S::f1方式去调用,不带self的,用<SearchData as S>::f2调用,相当于把具体的SearchData 类型向上转换成抽象的S类型之后再调用。

trait的具体实现会覆盖默认实现

struct SearchData{
    
}

trait S{
    fn f1(&self)-> i32{
        return 222;
    }
}

impl S for SearchData{
    fn f1(&self)-> i32{
        return 333;
    }
}

fn main() {
    let x=SearchData{};
    println!("{}",x.f1());
}

输出333

2个trait之间的同名函数会冲突,造成编译失败

struct SearchData{
    
}
trait S{
    fn f1(&self)-> i32;
}

impl S for SearchData{
    fn f1(&self)-> i32{
        return 111;
    }
}
trait S2:S{
    fn f1(&self)-> i32;
}

impl S2 for SearchData{
    fn f1(&self)-> i32{
        return 222;
    }
}

fn main() {
    let x=SearchData{};
    println!("{}",x.f1());
}

4,trait继承

trait A{
    fn funa();
}
trait B:A{
    fn funb();
}
trait C:A+B{
    fn func();
}
struct S{
}
impl A for S{
    fn funa(){
        println!("run a");
    }
}
impl B for S{
    fn funb(){
        println!("run b");
    }
}
impl C for S{
    fn func(){
        S::funa();
        println!("run c");
    }
}

注意,虽然有继承关系,但是 可见性却是平级的,父特征中的方法也可以调用子特征中的方法

例如,自定义排序是这么写的:

#[derive(Eq,PartialEq)]
struct Node{
    id:i32,
    num:i32
}
impl Ord for Node {
    #[inline]
    fn cmp(&self, other: &Node) -> Ordering {
        if self.num != other.num{
            return (*other).num.cmp(&self.num);
        }else{
            return self.id.cmp(&(*other).id);
        }
    }
}
impl PartialOrd for Node{
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        return Some(self.cmp(other)); 
    }
}

Ord依赖PartialOrd,但实现上却建议用partial_cmp调用cmp。

我是这么理解的, trait继承表达的是顶层的依赖关系,即设计层面的依赖关系,而trait内的函数调用是底层的依赖关系,即实现层面的依赖关系

5,trait的孤儿规则

孤儿规则:如果你想要为类型 A 实现特征 T,那么 A 或者 T 至少有一个是在当前作用域中定义的。

这条规则保证了代码的安全性,使得无关的代码不会互相影响。

6,trait的type成员

以减法为例

pub trait Sub<Rhs = Self> {
    type Output;
    fn sub(self, rhs: Rhs) -> Self::Output;
}

用法:

struct S{
    x:i32,
    y:f32
}

impl Sub for S{
    type Output = Self;
    fn sub(self,rhs:Self)->Self::Output{
        S{x:self.x-rhs.x,y:self.y-rhs.y}
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

rust 面向对象、trait 的相关文章

随机推荐

  • C语言之变量的存储方式和生存周期

    一 变量的存储方式 C语言变量的存储有两种方式 静态存储方式和动态存储方式 相应的生产期也有两种 静态生存期和自动生存期 静态存储方式 在程序运行前为变量内存分配内存 在程序结束后回收变量的内存 静态生存期 动态存储方式 在程序运行过程中
  • 网格布局 Grid

    网格布局 网格布局的API grid 布局将网页划分成一个个网格 可以任意组合不同的网格成 行和列 可以定义这些网格的大小 位置 层次等关系 从而实现各种各样的布局 Grid 布局远比 Flex 布局强大 弹性布局 flex 和 网格布局
  • 10个 Python 脚本来自动化你的日常任务

    在这个自动化时代 我们有很多重复无聊的工作要做 想想这些你不再需要一次又一次地做的无聊的事情 让它自动化 让你的生活更轻松 那么在本文中 我将向您介绍 10 个 Python 自动化脚本 以使你的工作更加自动化 生活更加轻松 因此 没有更多
  • 自动化生成测试脚本,点点点搞定性能测试!

    性能测试基于jmeter引擎 目前版本暂时没有设计存储于数据库 因此测试过程和结果数据都是属于实时一次性的 需要手动监控和保存数据 环境需要安装jdk1 8版本 当前Jmeter版本是5 6 2 把文件以及包含的报告汉化包放到Autotes
  • 【计算机毕设文章】微信小程序教师管理系统

    摘 要 随着我国经济迅速发展 人们对手机的需求越来越大 各种手机软件也都在被广泛应用 但是对于手机进行数据信息管理 对于手机的各种软件也是备受用户的喜爱 微信被用户普遍使用 为方便用户能够可以随时教师管理系统信息管理 特开发了基于微信小程序
  • Swift 响应式编程:简化 KVO 观察与 UI 事件处理 | 开源日报 No.110

    ReactiveX RxSwift Stars 23 8k License MIT RxSwift 是 Reactive Extensions 标准的 Swift 特定实现 它提供了 Observable 接口来表达计算的通用抽象 该项目旨
  • 离散数学知识点-期末复习

    目录 一 利用真值表求主析取范式 主合取范式 1 例题 二 推理证明 1 推理规则 2 例题 三 符号化命题 四 有穷集的计数 1 包含互斥原理 2 例题 1 文氏图法 2 包含互斥原理法 五 关系的闭包 1 三种闭包 2 Warshall
  • 【计算机毕设文章】实习记录小程序

    实习记录 摘 要 随着社会的发展 社会的方方面面都在利用信息化时代的优势 互联网的优势和普及使得各种系统的开发成为必需 本文以实际运用为开发背景 运用软件工程原理和开发方法 它主要是采用java语言技术和mysql数据库来完成对系统的设计
  • 走进暄桐教室 一起观看暄桐同学作品及感受

    暄桐是一间传统美学教育教室 创办于2011年 林曦是创办人和授课老师 教授以书法为主的传统文化和技艺 旨在以书法为起点 亲近中国传统之美 以实践和所得 滋养当下生活 其实 暄桐教室的写字画画课 不仅是林曦老师单方面的输出 而是有分享 也有回
  • 高频Postman接口测试面试题

    一 Postman在工作中使用流程是什么样的 新建集合管理 根据接口所属的模块 在集合中不同模块下编写接口测试用例 处理接口之间的数据关联操作 添加环境变量 在tests tab下中增加断言 调试接口 确保接口能被正常调用 批量运行用例或者
  • 【RBF分类】基于蜣螂算法优化径向基神经网络DBO-RBF实现故障诊断附matlab代码

    作者简介 热爱科研的Matlab仿真开发者 修心和技术同步精进 代码获取 论文复现及科研仿真合作可私信 个人主页 Matlab科研工作室 个人信条 格物致知 更多Matlab完整代码及仿真定制内容点击 智能优化算法 神经网络预测 雷达通信
  • 边缘概率密度

    对于二维连续型随机变量 设它的概率密度为 则 称 为 关于 的边缘概率密度 称 为 关于 的边缘概率密度
  • Bootstraps有什么含义?

    高级统计学习 自助法 js框架名 内核启动命令 C库名 java类加载器中的启动类加载器 BootstrapClassLoader
  • 其他:机器学习算法速查表

    概述 机器学习可以被认为是计算机科学中最有前途和最受期待的领域之一 借助先前的数据 机器学习试图使计算机能够独立学习新事物 机器学习模型接收数据 执行各种计算 并最大限度地提高模型的精度和准确度 机器学习的主要任务包括图像分割 语音识别和推
  • python渗透测试入门——流量嗅探器

    1 代码及代码讲解 代码编写工具 VsCode 1 socket嗅探器 首先第一个脚本是最简单的原始socket嗅探器 它只会读一个数据包 然后直接退出 import socket import os host to listen on H
  • 震精!京东T8大牛每天熬夜到凌晨三四点,竟然是在写Docker教程

    写在前面 Docker如日中天 这不是单纯的炒概念 Docker确确实实解决了开发与运维的痛点 因此在企业开发中得到了非常广泛的使用 Docker是一个开放源代码软件项目 让应用程序部署在软件容器下的工作可以自动化进行 借此在Linux操作
  • springboot基于安卓的一周穿搭App的设计与实现

    摘 要 相比于传统的一周穿搭管理方式 智能化的管理方式可以大幅提高一周穿搭的管理效率 实现了一周穿搭管理的标准化 制度化 程序化的管理 有效地防止了一周穿搭信息的随意管理 提高了信息的处理速度和精确度 能够及时 准确地查询和修正一周穿搭信息
  • 【计算机毕设文章】优购电商小程序

    优购电商小程序 摘 要 随着社会的发展 社会的方方面面都在利用信息化时代的优势 互联网的优势和普及使得各种系统的开发成为必需 本文以实际运用为开发背景 运用软件工程原理和开发方法 它主要是采用java语言技术和mysql数据库来完成对系统的
  • VLC播放器 fedora安装

    sudo dnf install y https download1 rpmfusion org free fedora rpmfusion free release rpm E fedora noarch rpm sudo dnf ins
  • rust 面向对象、trait

    目录 1 结构体 成员方法 2 trait 特征 3 同名函数的覆盖 冲突 4 trait继承 5 trait的孤儿规则 6 trait的type成员 给结构体添加方法有2种 一种是直接实现 一种的带trait的实现 直接实现的方式中 数据