当前位置: 首页 > 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.在文…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

Linux 下 DMA 内存映射浅析

序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存&#xff0c;但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程&#xff0c;可以参考这篇文章&#xff0c;我觉得写的非常…...

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法

用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法 大家好,我是Echo_Wish。最近刷短视频、看直播,有没有发现,越来越多的应用都开始“懂你”了——它们能感知你的情绪,推荐更合适的内容,甚至帮客服识别用户情绪,提升服务体验。这背后,神经网络在悄悄发力,撑起…...

作为点的对象CenterNet论文阅读

摘要 检测器将图像中的物体表示为轴对齐的边界框。大多数成功的目标检测方法都会枚举几乎完整的潜在目标位置列表&#xff0c;并对每一个位置进行分类。这种做法既浪费又低效&#xff0c;并且需要额外的后处理。在本文中&#xff0c;我们采取了不同的方法。我们将物体建模为单…...