当前位置: 首页 > news >正文

Rust的运行时多态

Rust的运行时多态

Rust的静态多态即编译时多态,通过**泛型+特征约束(Generic Type + Trait Constrait)**来实现;

那么动态多态(运行时多态)呢?答案是特征对象(Trait Object)

特征对象不是一个实例,而是一个结构体类型。

语法是dyn TraitName,编译时指示某个对象是实现TraitName的类型,其具体类型未知。

分析

程序运行时,要调用一个特征方法,需要两个要素:

  • 对象实例(对象类型未知,因此其编译期大小未知)
  • 特征的方法表

所以特征对象结构体必须获知以上两个要素。

发生运行时多态时,在编译阶段编译器无法辨别对象实例的类型,因此对象实例要素的大小无法获知,进而特征对象(Trait Object)的大小在编译阶段无法被确定,这决定了Trait Object只能存放在堆上,通过引用或智能指针来访问

指向特征对象的引用或智能指针,包含了两个指针成员,在程序运行时,ptr1在指向对象实例,ptr2指向该对象类型的Trait Method实现。

典型用例


#[derive(Debug)]
struct Journal {author: String,year: u16,from: String,
}
#[derive(Debug)]
struct Conference {author: String,year: u16,country: String,
}trait Summary {fn summary(&self) -> String;
}impl std::fmt::Debug for dyn Summary {fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {write!(f, "{}", self.summary())}
}impl Summary for Journal {fn summary(&self) -> String {format!("{}\t{}\t{}", self.author, self.year, self.from)}
}
impl Summary for Conference {fn summary(&self) -> String {format!("{}\t{}\t{}", self.author, self.year, self.country)}
}// can't defer concrete type in compile stage, trait constrain can't used here
// fn init_default(_type: &str) -> impl Summary {
//     if _type == "journal" {
//         Journal {
//             author: "hjd".to_owned(),
//             year: 2018,
//             from: "Nature".to_owned(),
//         }
//     } else {
//         Conference {
//             author: "hjd".to_owned(),
//             year: 2018,
//             country: "China".to_owned(),
//         }
//     }
// }// 只能使用特征对象进行动态分发,因为返回类型编译期无法推理获知
fn init_default(_type: &str) -> Box<dyn Summary> {if _type == "journal" {Box::new(Journal {author: "hjd".to_owned(),year: 2018,from: "Nature".to_owned(),})} else {Box::new(Conference {author: "hjd".to_owned(),year: 2018,country: "China".to_owned(),})}
}fn main() {let p1 = init_default("journal");let p2 = init_default("conference");let p3 = init_default("journal");let p4 = init_default("conference");let p_list = vec![p1, p2, p3, p4];// dyn Summary是一个特征对象类型,它忘记了自己之前的具体类型,只能调用Summary特征中的方法for p in p_list.iter() {println!("{:?}", p);}
}

相关文章:

Rust的运行时多态

Rust的运行时多态 Rust的静态多态即编译时多态&#xff0c;通过**泛型特征约束&#xff08;Generic Type Trait Constrait&#xff09;**来实现&#xff1b; 那么动态多态&#xff08;运行时多态&#xff09;呢&#xff1f;答案是特征对象&#xff08;Trait Object&#xff…...

sqllabs通关

sqllabs5:(报错注入) ?id1 回显You are in........... ?id2-1 回显You are in........... ?id1 回显 1 LIMIT 0,1 判断是字符型&#xff0c;闭合。?id1order by 3-- //页面显示正常我们试了4行得出是报错注入 我们先爆库名 http://127.0.0.1/sqli-labs-master/L…...

RTSP系列四:RTSP Server/Client实战项目

RTSP系列&#xff1a; RTSP系列一&#xff1a;RTSP协议介绍-CSDN博客 RTSP系列二&#xff1a;RTSP协议鉴权-CSDN博客 RTSP系列三&#xff1a;RTP协议介绍-CSDN博客 RTSP系列四&#xff1a;RTSP Server/Client实战项目-CSDN博客 目录 一、RTSP Server实战项目 1、准备 2、…...

sqli-labs-php7-master第11-16关

猜注入点 先来猜数字型 单引号字符型&#xff1a; 发现注入点找到了 猜测数据库有多少个字段&#xff1a; 1’ order by 4 # 密码随便输的。 这里没有使用--注释&#xff0c;因为没作用&#xff0c;可能是过滤掉了 继续猜。刚才没猜对 1 order by 2 # 没报错&#xff0c;猜…...

c++初阶 string的底层实现

string 基础函数成员成员变量构造函数析构函数&#xff1a;拷贝构造赋值构造 遍历下标访问迭代器 增删插开辟空间push_backappendinserterase 功能函数swapfindc_strsubstrclear 其他函数比较函数流提取<<流插入>>getline 完整版 声明&#xff1a;非纯手搓&#xf…...

微信小程序实现上传照片功能

案例&#xff1a; html: <view class"zhengjianCont fontSize30" style"margin-bottom: 40rpx;"><view class"kuai"><image binderror"imageOnloadError" bind:tap"upladPhoto" data-params"business…...

lombok安装成功但是找不到方法

2024.1.1版本的IDE的插件安装了默认的lombok&#xff08;如图1&#xff09;&#xff0c;pom文件中也引入了lombok的依赖&#xff0c;在实体类写了Data的注解&#xff0c;当调用实体类的get和set方法运行时&#xff0c;报错找不到相应的方法&#xff0c;但是在调用get、set方法的…...

单细胞Seurat的umi矩阵-与feature、counts(用于质控)

目录 关于umi矩阵学习 用umi计算feature、counts值 ①meta数据查看 ②Count和Feature计算(生成Seurat时自动计算) 1)提取UMI矩阵 2)计算 其他指标 评估质量指标(重点) 1)UMI计数 2)基因计数 3)UMIs vs. genes detected 4)线粒体计数比率 5)综合过滤 过…...

安防视频监控EasyCVR视频汇聚平台设备发送了GPS位置,但是订阅轨迹为空是什么原因?

安防视频监控EasyCVR视频汇聚平台兼容性强、支持灵活拓展&#xff0c;平台可提供视频远程监控、录像、存储与回放、视频转码、视频快照、告警、云台控制、语音对讲、GIS地图、轨迹跟踪、平台级联等视频能力。 用户描述&#xff0c;设备在电子地图中可以查看到定位信息&#xff…...

在 VueJS 中使用事件委托处理点击事件(事件委托,vue事件委托,什么是事件委托,什么是vue的事件委托)

前言 在开发 Vue 项目时&#xff0c;我们经常需要处理大量的点击事件。为每个可点击的元素单独添加事件监听器不仅会增加代码的复杂度&#xff0c;还会降低性能。事件委托是一种有效的优化方式&#xff0c;它可以显著减少事件监听器的数量&#xff0c;提高代码的可维护性和执行…...

密码学简史:时间密语

​ 注&#xff1a;机翻&#xff0c;未校。 A brief history of cryptography: Sending secret messages throughout time Stemming from the Greek words for “hidden writing,” cryptography is the practice of encrypting transmitted information so that it can only b…...

【Java数据结构】---初始数据结构

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 &#xff0c;Java 欢迎大家访问~ 创作不易&#xff0c;大佬们点赞鼓励下吧~ 前言 从今天开始我们就要学习Java…...

MySQL--主从复制

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、什么是主从复制 1、定义 主从复制&#xff0c;是用来建立一个和主数据库完全一样的数据库环境&#xff0c;称为从数据库&#xff1b;主数据库一…...

Linux RT调度器之负载均衡

RT调度类的调度策略是&#xff1a;保证TopN&#xff08;N为系统cpu个数&#xff09;优先级的任务可以优先获得cpu资源。除了在任务选核时通过基于cpu优先级的选核策略保证这一点外&#xff0c;还有其它流程&#xff0c;我们姑且将这部分流程称作RT调度器的负载均衡&#xff08;…...

pwn学习笔记(8)--初识Pwn沙箱

初识Pwn沙箱 ​ 沙箱机制&#xff0c;英文sandbox&#xff0c;是计算机领域的虚拟技术&#xff0c;常见于安全方向。一般说来&#xff0c;我们会将不受信任的软件放在沙箱中运行&#xff0c;一旦该软件有恶意行为&#xff0c;则禁止该程序的进一步运行&#xff0c;不会对真实系…...

Day18_2--Vue.js Ajax(使用 Axios)基础入门学习

Vue.js 中的 Ajax 请求&#xff08;使用 Axios&#xff09; 什么是 Axios&#xff1f; Axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;可以用于浏览器和 Node.js 环境中。它是现代化的 Ajax 库&#xff0c;用来替代传统的 XMLHttpRequest。 为什么选择 Axios&#xf…...

windows11远程桌面如何打开

随着远程办公的普及&#xff0c;选择合适的远程桌面工具变得尤为重要。在Windows 11上&#xff0c;用户可以利用系统自带的远程桌面功能&#xff0c;或选择更专业的第三方解决方案&#xff0c;如Splashtop。本文将详细介绍如何在Windows 11上启用远程桌面&#xff0c;并对比Win…...

qt代码显示,包含文本颜色设置等

QScintilla 安装示例代码参考链接 安装 最近发现了一个有趣的库&#xff0c;qt的插件库&#xff0c;之前一直以为显示代码时是重写QTextEdit来实现的&#xff0c;结果qt有现成的一个库来显示这些东西&#xff0c;在此记录一下 # 安装 QScintilla pip install QScintilla示例代码…...

抽象代数精解【6】

文章目录 简单密码算法模运算数学定义置换移位代换仿射 参考文献 简单密码算法 模运算数学定义 模m剩余类集 Z m Z_m Zm​ 设∀a,b∈Z&#xff08;整数&#xff09;&#xff0c;m为正整数 m|b-a &#xff0c;称a R b R满足反身性、对称性、传递性 1、R为同余关系&#xff0c;…...

如何选择合适的PCB材料?FR4、陶瓷、还是金属基板?

选择合适的PCB材料对于电路板的性能、可靠性和成本至关重要。不同的PCB材料具有不同的特性&#xff0c;适用于不同的应用场景。 01 FR4&#xff08;玻璃纤维环氧树脂&#xff09; FR4的特点&#xff1a; 广泛应用&#xff1a;FR4是最常见的PCB基板材料&#xff0c;广泛应用…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...

Qt的学习(一)

1.什么是Qt Qt特指用来进行桌面应用开发&#xff08;电脑上写的程序&#xff09;涉及到的一套技术Qt无法开发网页前端&#xff0c;也不能开发移动应用。 客户端开发的重要任务&#xff1a;编写和用户交互的界面。一般来说和用户交互的界面&#xff0c;有两种典型风格&…...

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!

【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...

数据库——redis

一、Redis 介绍 1. 概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的内存键值数据库系统&#xff0c;具有以下核心特点&#xff1a; 内存存储架构&#xff1a;数据主要存储在内存中&#xff0c;提供微秒级的读写响应 多数据结构支持&…...