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

【Rust 基础篇】Rust Sized Trait:理解Sized Trait与动态大小类型

导言

Rust是一门以安全性和性能著称的系统级编程语言。在Rust中,类型大小的确定在编译期是非常重要的。然而,有些类型的大小在编译期是无法确定的,这就涉及到了Rust中的动态大小类型(DST)。为了保证在编译期可以确定类型的大小,Rust引入了Sized trait。本篇博客将深入探讨Rust中的Sized trait,包括Sized trait的定义、作用、使用方法,以及Sized trait与动态大小类型的关系,以便读者全面了解Rust中的类型大小问题,编写更安全、高效的代码。

1. 什么是Sized Trait?

在Rust中,Sized是一个特殊的trait,它用于标识类型是否在编译期已知大小。Sized trait的定义如下:

pub trait Sized {// 该trait没有任何方法,用于标识类型是否具有确定的大小
}

需要注意的是,所有的类型默认都是Sized的,除非使用特殊语法来标识为不具有确定大小的动态大小类型。

2. 动态大小类型与Sized Trait的关系

在Rust中,动态大小类型(DST)是一种特殊的类型,它的大小在编译期无法确定,需要在运行时根据实际情况确定。动态大小类型主要包括引用类型和trait对象。而Sized trait用于标识类型是否在编译期已知大小。

2.1 引用类型与Sized Trait

引用类型是Rust中的动态大小类型之一。在Rust中,引用类型是通过引用(&)来引用其他类型的值。引用类型的大小在编译期是无法确定的,因为它的大小取决于被引用的值的大小。

fn main() {let x = 42;let reference = &x; // 引用x的值
}

在上述例子中,我们创建了一个变量x,然后通过引用(&)创建了一个引用reference,引用了变量x的值。引用类型的大小在编译期无法确定,因为它的大小取决于被引用的值的大小。

然而,引用类型并不是一个动态大小类型,因为它并没有在编译期确定大小的问题。引用类型总是具有固定的大小,即&T类型的大小总是等于指针的大小。这是因为引用的值总是存在于堆栈中,而不是存储在引用本身中。

2.2 trait对象与Sized Trait

trait对象是Rust中的另一种动态大小类型。在Rust中,trait对象是通过trait来引用具体类型的值,使得这些值可以按照相同的trait进行操作。trait对象的大小在编译期是无法确定的,因为它的大小取决于具体类型的大小。

trait Shape {fn area(&self) -> f64;
}struct Circle {radius: f64,
}impl Shape for Circle {fn area(&self) -> f64 {self.radius * self.radius * std::f64::consts::PI}
}fn main() {let circle: Circle = Circle { radius: 5.0 };let shape: &dyn Shape = &circle; // 通过trait对象引用具体类型的值
}

在上述例子中,我们定义了一个trait Shape,并为具体类型Circle实现了该trait。然后,我们通过trait对象&dyn Shape来引用具体类型Circle的值。trait对象的大小在编译期无法确定,因为它的大小取决于具体类型的大小。

在trait对象中,存在一个隐藏的指针,用于存储具体类型的值,并通过该指针来调用具体类型的方法。因此,trait对象的大小是固定的,即&dyn Trait类型的大小等于一个指针的大小。

2.3 Sized Trait的限制

在Rust中,动态大小类型(DST)有一些限制,特别是在泛型和trait实现中。

2.3.1 泛型中的Sized Trait限制

在泛型中,如果要使用动态大小类型,则需要使用?Sized语法来标识。

// 错误示例:无法使用动态大小类型作为泛型参数
fn process_data<T>(data: &[T]) {// 处理数据
}fn main() {let vec_data = vec![1, 2, 3, 4, 5];process_data(&vec_data); // 编译错误:动态大小类型不能用作泛型参数
}

在上述错误示例中,我们尝试在泛型函数process_data中使用动态大小类型[T]作为参数,但这是不允许的。为了允许使用动态大小类型作为泛型参数,我们需要使用?Sized语法来标识。

// 正确示例:使用动态大小类型作为泛型参数
fn process_data<T: ?Sized>(data: &[T]) {// 处理数据
}fn main() {let vec_data = vec![1, 2, 3, 4, 5];process_data(&vec_data); // 正确:使用动态大小类型作为泛型参数
}

在上述正确示例中,我们使用了?Sized语法来标识T可以是动态大小类型,从而允许使用动态大小类型作为泛型参数。

2.3.2 trait实现中的Sized Trait限制

在Rust中,为了安全性考虑,如果要为trait实现动态大小类型,必须使用?Sized语法来标识。这是因为对于trait对象,编译器需要在运行时动态地确定具体类型的大小,而不是在编译期确定。

trait Shape {fn area(&self) -> f64;
}struct Circle {radius: f64,
}impl Shape for Circle {fn area(&self) -> f64 {self.radius * self.radius * std::f64::consts::PI}
}// 错误示例:无法为trait实现动态大小类型
impl Shape for dyn Shape {fn area(&self) -> f64 {// 实现trait方法}
}fn main() {let circle: Circle = Circle { radius: 5.0 };let shape: &dyn Shape = &circle;shape.area();
}

在上述错误示例中,我们尝试为trait Shape实现动态大小类型,但这是不允许的。为了允许为trait实现动态大小类型,我们需要使用?Sized语法来标识。

// 正确示例:使用?Sized语法为trait实现动态大小类型
impl Shape for dyn Shape + ?Sized {fn area(&self) -> f64 {// 实现trait方法}
}fn main() {let circle: Circle = Circle { radius: 5.0 };let shape: &dyn Shape = &circle;shape.area();
}

在上述正确示例中,我们使用了?Sized语法来标识dyn Shape可以是动态大小类型,从而允许为trait实现动态大小类型。

3. 使用方法

3.1 检查类型是否满足Sized Trait

在Rust中,我们可以使用is_sized函数来检查类型是否满足Sized Trait。

fn main() {println!("i32 is Sized: {}", std::mem::size_of::<i32>() == std::mem::size_of::<i32>());println!("&i32 is Sized: {}", std::mem::size_of::<&i32>() == std::mem::size_of::<usize>());
}

在上述例子中,我们使用is_sized函数来检查i32&i32是否满足Sized Trait。由于i32是Sized类型,因此输出为true,而&i32是引用类型,也是Sized类型,输出为true

3.2 使用Sized Trait来约束泛型

在泛型中,我们可以使用Sized Trait来约束类型是否满足Sized。

fn process_data<T: Sized>(data: &[T]) {// 处理数据
}fn main() {let vec_data = vec![1, 2, 3, 4, 5];process_data(&vec_data); // 正确:Sized类型作为泛型参数
}

在上述例子中,我们使用Sized Trait来约束泛型函数process_data的参数类型,确保只有Sized类型才能作为泛型参数。

3.3 使用?Sized来实现动态大小类型

当需要为trait实现动态大小类型时,可以使用?Sized语法来标识。

trait Shape {fn area(&self) -> f64;
}struct Circle {radius: f64,
}impl Shape for Circle {fn area(&self) -> f64 {self.radius * self.radius * std::f64::consts::PI}
}impl Shape for dyn Shape + ?Sized {fn area(&self) -> f64 {// 实现trait方法}
}fn main() {let circle: Circle = Circle { radius: 5.0 };let shape: &dyn Shape = &circle;shape.area();
}

在上述例子中,我们使用了?Sized语法来标识dyn Shape可以是动态大小类型,从而允许为trait实现动态大小类型。

4. 动态大小类型与Sized Trait的比较

虽然动态大小类型和Sized Trait都涉及到类型大小的确定,但它们有着不同的含义和用途。

动态大小类型是一种特殊的类型,它的大小在编译期无法确定,需要在运行时根据实际情况确定。动态大小类型主要包括引用类型和trait对象。在使用动态大小类型时,需要注意其限制,如无法直接实例化、泛型中的限制等。

而Sized Trait是一个特殊的trait,用于标识类型是否在编译期已知大小。所有的类型默认都是Sized的,除非使用特殊语法来标识为不具有确定大小的动态大小类型。Sized Trait的作用是用于泛型和trait实现中,约束类型是否满足Sized。

结论

本篇博客对Rust中的Sized Trait进行了深入解释和说明,包括Sized Trait的定义、作用、使用方法,以及与动态大小类型的关系和比较。Sized Trait在Rust中是一个非常重要的概念,它用于标识类型是否在编译期已知大小,保证类型的大小在编译期可以确定。通过深入理解和正确使用Sized Trait,我们可以编写更安全、高效的代码,充分发挥Rust语言的优势。希望通过本篇博客的阐述,读者能够全面了解Rust中的Sized Trait,为编写优秀的Rust代码打下坚实的基础。谢谢阅读!

相关文章:

【Rust 基础篇】Rust Sized Trait:理解Sized Trait与动态大小类型

导言 Rust是一门以安全性和性能著称的系统级编程语言。在Rust中&#xff0c;类型大小的确定在编译期是非常重要的。然而&#xff0c;有些类型的大小在编译期是无法确定的&#xff0c;这就涉及到了Rust中的动态大小类型&#xff08;DST&#xff09;。为了保证在编译期可以确定类…...

前端框架学习-Vue(三)

目录 初识VueVue模板语法数据绑定el和data的两种写法事件的基本使用$emit在子组件中定义方法&#xff0c;执行父组件的方法 Vue中的事件修饰符&#xff1a;键盘事件计算属性监视属性条件渲染列表渲染表单数据收集过滤器 笔记内容来自&#xff1a;尚硅谷Vue2.0Vue3.0全套教程丨v…...

HTML <rt> 标签

实例 一个 ruby 注释&#xff1a; <ruby> 漢 <rt> ㄏㄢˋ </rt> </ruby>浏览器支持 元素ChromeIEFirefoxSafariOpera<rt>5.05.538.05.015.0 Internet Explorer 9, Firefox, Opera, Chrome 以及 Safari 支持 <rt> 标签。 注释&#xf…...

VMware Linux Centos 配置网络并设置为静态ip

在root用户下进行以下操作 1. 查看子网ip和网关 &#xff08;1&#xff09;进入虚拟网络编辑器 &#xff08;2&#xff09;进入NAT设置 &#xff08;3&#xff09;记录子网IP和子网掩码 2. 修改网络配置文件 &#xff08;1&#xff09;cd到网络配置文件路径下 [rootlo…...

【Leetcode 30天Pandas挑战】学习记录

这个系列难度比较低&#xff0c;一题写一篇其实没必要&#xff0c;就全部放到一篇吧 题目列表&#xff1a; 595. Big Countries1757. Recyclable and Low Fat Products 595. Big Countries 原题链接&#xff1a;595. Big Countries Table: World ---------------------- | C…...

微信小程序使用 canvas 2d 实现签字板组件

本文是在微信小程序中使用 canvas 2d 来实现签字板功能&#xff1b; 效果图&#xff1a; 代码&#xff1a; 1、wxml <view><canvas id"canvas"type"2d"bindtouchstart"start"bindtouchmove"move"bindtouchend"end&qu…...

区块链赋能新时代司法体系,中移链打造可信存证服务

近期&#xff0c;某百万级粉丝网红的法律维权之路引发社会关注。其在面对网络造谣行为时积极搜集证据&#xff0c;使用区块链技术将相关信息上链保全&#xff0c;然后将造谣者全部起诉&#xff0c;一系列操作被广大网友喻为是教科书式网络维权。 科技在发展&#xff0c;时代在…...

ELK报错no handler found for uri and method [PUT] 原因

执行后提示no handler found for uri and method post&#xff0c;最新版8.2的问题&#xff1f; 原因&#xff1a; index.mapping.single_type: true在索引上 设置将启用按索引的单一类型行为&#xff0c;该行为将在6.0后强制执行。 原 {type} 要改为 _doc&#xff0c;格式如…...

Sublime操作技巧笔记

同时选中2个文件&#xff1a;自动切换成左右2个界面 格式化代码ctrlshifth&#xff1a; 使用快捷键ctrl shift p调出控制台&#xff0c;输入install package&#xff0c;然后输入html-css-js prettify&#xff0c;进行下载。具体的快捷键在preference > package setting &g…...

JVM | 基于类加载的一次完全实践

引言 我在上篇文章&#xff1a;JVM | 类加载是怎么工作的 中为你介绍了Java的类加载器及其工作原理。我们简单回顾下&#xff1a;我用一个易于理解的类比带你逐步理解了类加载的流程和主要角色&#xff1a;引导类加载器&#xff0c;扩展类加载器和应用类加载器。并带你深入了解…...

Termux实现电脑端远程操作【开启SSH的完整教程】

文章目录 前言一、安装软件1、安装2、启动服务3、特别说明4、添加key二、电脑端连接1、查看ip2、电脑端连接总结前言 上篇文章【安卓手机变身Linux服务器】讲了如何将你的上古安卓手机变废为宝,这节着重为大家解决一个痛点:“手机上操作实在是不方便”。 一、安装软件 1、安…...

java(Collection类)

文章目录 Collection接口继承树Collection接口及方法判断删除其它 Iterator(迭代器)接口迭代器的执行原理 foreach循环Collection子接口1&#xff1a;ListList接口特点List接口方法List接口主要实现类&#xff1a;ArrayListList的实现类之二&#xff1a;LinkedListList的实现类…...

VS2019编译安装OpenMesh8.0

文章目录 一、简介二、相关准备三、编译安装四、举个栗子参考资料一、简介 多边形网格一直以来就是交互式3D图形应用程序中最合适的几何表示,它们足够灵活,可以近似任意形状,并且可以通过当前的图形硬件有效地处理,即使在今天的低成本电脑上也是如此。OpenMesh便是其中一种…...

Python爬虫遇到URL错误解决办法大全

在进行Python爬虫任务时&#xff0c;遇到URL错误是常见的问题之一。一个错误的URL链接可能导致爬虫无法访问所需的网页或资源。为了帮助您解决这个问题&#xff0c;本文将提供一些实用的解决方法&#xff0c;并给出相关代码示例&#xff0c;希望对您的爬虫任务有所帮助。 一、…...

基于Vue+ElementUI+Echarts+G2Plot的大屏设计器,代码完全开源

简介 &#x1f525;DataRoom是一款基于SpringBoot、MyBatisPlus、ElementUI、G2Plot、Echarts等技术栈的大屏设计器&#xff0c;具备大屏设计、预览、资源管理、组件管理等能力&#xff0c;支持JSON、MySQL、Oracle、PostgreSQL、HTTP、JavaScript、Groovy等数据集接入&#x…...

Linux - PostgreSQL 适用于9.x 以上的 tar.gz 源码安装与理解 - 报错集锦

这里写目录标题 序言主要内容bash 配置文件个人理解关于初始化 PostgreSQL 数据库的理解 启动方法检查服务器是否在PostgreSQL中运行关闭 postgresql 数据库方法参考链接 序言 PostgreSQL 9.x 以下版本笔者没用过&#xff0c;具体操作看参考链接&#xff0c;笔者就不记录重复操…...

Django使用用户列表的展示和添加

接着上一篇&#xff1a;https://blog.csdn.net/javascript_good/article/details/132027702 来实现用户表的查询和添加 1、创建数据库表 在models.py 中&#xff0c;增加UserInfo类&#xff0c;包括字段姓名、密码、年龄、账号余额、入职时间、所属部门、性别 verbose_name 就…...

kubernetes错误汇总

title: “kubernetes错误汇总” categories: - “技术” tags: - “Kubernetes” - “错误汇总” toc: false original: true draft: false 1、增加 master etcd 报错 1.1、错误描述 由于创建的k8s集群&#xff0c;其中有一个master节点初始化失败&#xff0c;先删除了这个节…...

[openCV]基于拟合中线的智能车巡线方案V4

import cv2 as cv import os import numpy as np# 遍历文件夹函数 def getFileList(dir, Filelist, extNone):"""获取文件夹及其子文件夹中文件列表输入 dir&#xff1a;文件夹根目录输入 ext: 扩展名返回&#xff1a; 文件路径列表"""newDir d…...

【网络云盘客户端】——上传文件的功能的实现

目录 上传文件功能的实现 uploadtask的设计 设置上传的槽函数 uploadFileAction接口 uploadFile接口 定时上传文件 进度条的设计 上传文件功能的实现 上传文件功能实现 1.双击 ”上传文件 “的 QListWidgetItem 或者 点击 “上传” 菜单项 都会弹出一个文件对话框 2.在文…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...