Rust开发——切片(slice)类型
1、什么是切片
在 Rust 中,切片(slice)是一种基本类型和序列类型。在 Rust 官方文档中,切片被定义为“对连续序列的动态大小视图”。
但在rust的Github 源码中切片被定义如下:
切片是对一块内存的视图,表示为指针和长度。
其实这个定义更有帮助。从这里的定义可以知道,切片是一个“宽指针”(fat pointer)。所以基本上,当创建一个数组的切片时,切片包含以下内容:
- 指向数组中切片起始元素地址的指针
- 描述切片长度的值
2、切片示例
在 Rust 中,切片可以是对支持的数组的视图,也可以是对其他序列(例如向量或字符串)的视图。如果切片是对字符串的视图,它被称为字符串切片或字符串字面量,并且通常以其借用形式 &str 出现。
以下是一个示例数组和该数组生成的两个切片:

左边和右边展示了对中间显示的数组提供视图的两个切片。数组和切片的定义如下:
let array: [i32; 10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let slice1 = &array[5..10];
let slice2 = &array[3..7];
从上图可以看到,在 slice1 中,切片的指针指向数组的索引 5。slice1 的长度为 5。这意味着切片将包含数组中的 5 个元素。下面是切片相关的索引和值。切片本身的索引从 0 到 4。
右侧是 slice2。该切片的指针指向元素 3,且切片的长度为 4。
3、切片常规操作
定义一个数组,然后对数组进行切片操作:
let array: [i32; 7] = [0, 1, 2, 3, 4, 5, 6];let slice = &array[..]; // [ 0, 1, 2, 3, 4, 5, 6 ]
let slice = &array[0..3]; // [ 0, 1, 2 ]
let slice = &array[..3]; // [ 0, 1, 2 ]
let slice = &array[2..4]; // [ 2, 3 ]
let slice = &array[2..]; // [ 2, 3, 4, 5, 6 ]
上面定义了不可变数组以及创建数组切片的几种方法。在切片定义后的注释中展示了 dbg!(slice); 的输出结果。
之后再创建一个可变的切片:
let mut array: [i32; 7] = [0, 1, 2, 3, 4, 5, 6];
let array_slice = &mut array[0..5]; // [ 0, 1, 2, 3, 4 ]

检查切片的长度并迭代索引/值:
slice.len(); // 5for (index, item) in slice.iter().enumerate() {println!("index: {:?} element {:?}", index, item);
}
/*
index: 0 element 0
index: 1 element 1
index: 2 element 2
index: 3 element 3
index: 4 element 4
*/
从切片中检索一个值:
slice[1]; // 1
切片的长度在编译时并不总是已知的。如果访问超出边界的索引值,编译器将不会保存:
slice[100];
会报如下错误:
thread ‘main’ panicked at ‘index out of bounds: the len is 5 but the index is 100’
为了安全地从切片中获取值,可以使用 get() 方法:
slice.get(2); // Some(2)
slice.get(100); // None
在切片中查找值:
slice.iter().position(|v| v == &120); // None
slice.iter().position(|v| v == &4); // Some(4)
改变切片中元素的值:
slice[0] = 100;
dbg!(slice); // [100, 1, 2, 3, 4]
dbg!(array); // [100, 1, 2, 3, 4, 5, 6]
4.对不同类型的切片进行操作
可以从数组、向量和字符串中获取切片:
let array: [i32; 4] = [0, 1, 2, 3];
let array_slice = &array[..2]; // [0, 1]
let vector = vec![1, 2, 3, 4];
let vector_slice = &vector[0..2]; // [1, 2]
let string = String::from("string slice");
let string_slice = &string[0..6]; // "string"
println!("{:?} {:?} {:?}", array_slice, vector_slice, string_slice);
// [0, 1] [1, 2] "string"
之前定义的数组和向量包含 i32 类型,之后可以创建一个同时适用于 vector_slice 和 array_slice 的函数:
fn return_second(n: &[i32]) {println!("{}", n[1]);
}
return_second(array_slice); // 1
return_second(vector_slice); // 2
字符串切片是一个 &str,因此不能将其传递给 return_second 函数。事实上,字符串切片有点特殊。在 Rust 中,所有的字符串都是 UTF-8 编码的,因此字符的大小可以不同。iter() 方法不能用在字符串切片上,相反,需要使用 chars() 方法。要从切片中取第 n 个字符,则需要使用索引 n。
let string = String::from("Rust is 😍");
let string_slice = &string[..];fn return_second_char(n: &str) {println!("{:?}", n.chars().nth(1));
}return_second_char(string_slice); // Some('u')for c in string_slice.chars() {println!("{}", c)
}
/*
R
u
s
ti
s😍
*/
for (i, c) in string_slice.chars().enumerate() {println!("{} {}", i, c)
}
/*
0 R
1 u
2 s
3 t
4
5 i
6 s
7
8 😍
*/
5.指针
Rust中的宽指针(fat pointers)与窄指针(thin pointers)是指针类型的两种概念。
-
窄指针(Thin Pointers):指针仅包含目标内存地址信息,不包含其他附加信息。比如,裸指针
*const T和*mut T就是窄指针,它们只存储指向某个类型T的内存地址。 -
宽指针(Fat Pointers):指针除了存储目标内存地址外,还包含其他信息,例如动态数组的长度。切片
&[T]或者动态 trait 对象&dyn Trait就是宽指针的例子,它们除了指向内存的地址外,还存储着长度等其他信息。
宽指针包含更多的信息,但也会带来一些额外的存储开销。窄指针更加轻量,但缺乏一些额外的信息。在Rust中,切片是一种宽指针,因为它包含指向数据的指针和数据长度。
use std::mem;
let array: [i32; 500] = [0; 500];
let slice = &array[..];
let array_pointer = &array;
let slice_pointer = &slice;
let start_of_array_slice = &array[0];
println!("--------------------------------------------");
println!("array_pointer address: {:p}", array_pointer);
println!("slice_pointer address: {:p}", slice_pointer);
println!("start_of_array_slice address: {:p}", start_of_array_slice);
println!("slice occupies {} bytes", mem::size_of_val(&slice));
println!("array_pointer occupies {} bytes",mem::size_of_val(&array_pointer)
);
println!("array occupies {} bytes", mem::size_of_val(&array));
println!("--------------------------------------------");
--------------------------------------------
array_pointer address: 0x9def68
slice_pointer address: 0x9df738
start_of_array_slice address: 0x9def68
slice occupies 16 bytes
array_pointer occupies 8 bytes
array occupies 2000 bytes
--------------------------------------------
数组的总大小为 2000 字节。整个数组的切片(宽指针)占据 16 字节。如果获取数组的指针,得到的是一个占据 8 字节的窄指针。数组指针和切片起始地址的内存地址是相同的。
相关文章:
Rust开发——切片(slice)类型
1、什么是切片 在 Rust 中,切片(slice)是一种基本类型和序列类型。在 Rust 官方文档中,切片被定义为“对连续序列的动态大小视图”。 但在rust的Github 源码中切片被定义如下: 切片是对一块内存的视图,表…...
如何给shopify motion主题的产品系列添加description
一、Description是什么 Description是一种HTML标签类型,通过指定Description的内容,可以帮助搜索引擎以及用户更好的理解当前网页包含的主要了内容。 二、Description有什么作用 1、基本作用,对于网站和网页做一个简单的说明。 2、吸引点击&…...
力扣刷题-二叉树-二叉树最小深度
给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明:叶子节点是指没有子节点的节点。(注意题意) 示例 1: 输入:root [3,9,20,null,null,15,7] 输出&#x…...
注解方式优雅的实现 Redisson 分布式锁
1前言 日常开发中,难免遇到一些并发的场景,为了保证接口执行的一致性,通常采用加锁的方式,因为服务是分布式部署模式,本地锁Reentrantlock和Synchnorized这些就先放到一边了,Redis的setnx锁存在无法抱保证…...
PHP/Laravel通过经纬度计算距离获取附近商家
实际开发中,常常需要获取用户附近的商家,思路是 获取用户位置(经纬度信息)在数据库中查询在距离范围内的商家 注: 本文章内计算距离所使用地球半径统一为 6378.138 km public function mpa_list($latitude,$longitude,$distance){// $latitude 34.306465;// $longitude 10…...
grafana面板介绍
grafana 快速使用 背景 随着公司业务的不断发展,紧接来的是业务种类的增加、服务器数量的增长、网络环境的越发复杂以及发布更加频繁,从而不可避免地带来了线上事故的增多,因此需要对服务器到应用的全方位监控,提前预警…...
实验三 循环结构程序设计(Python)
第1关:打印图形 zm=input("") #代码开始#代码结束def print_pattern(letter):if not letter.isalpha() or not letter.isupper():print("请输入大写字母")returnstart_char = Aend_char = letterfor i in range(ord(start_char), ord(end_char) + 1):spa…...
Flutter笔记:目录与文件存储以及在Flutter中的使用(上)
Flutter笔记 目录与文件存储以及在Flutter中的使用(上) 文件系统基础知识与路径操作 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:h…...
注意了!申请流量卡时地址一定不要填写学校,不好下卡哦!
当我们在网上购买流量卡时,都会要求让填写准确的收货地址,但是对于收货地址你填对了吗? 很多朋友在提交流量卡申请之后,往往会被运营商拒审,对于拒审的原因除了比较常见的信息填写有有误、涉及禁发地区、重复申…...
minio使用shell上传文件
minio使用shell上传文件 前言1. 编写调用脚本2.测试脚本上传3.候选脚本 前言 业务场景需要实现,服务器文件上传至存储服务。一种方式是安装minio的linux客户端,另一种方式是通过调用minio的api接口实现文件上传。后一种方式不需要依赖minio的客户端使用…...
LeetCode538. Convert BST to Greater Tree
文章目录 一、题目二、题解 一、题目 Given the root of a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus the sum of all keys greater than the original key in BST. As a remin…...
iPaaS和RPA,企业自动化应该如何选择?
全球著名的咨询调查机构Gartner在2022年初再次发布了《2022年12大技术趋势》报告。 Gartner是全球最具权威的IT研究与顾问咨询公司,成立于1979年,在界定及分析那些决定了商业进程的发展趋势与技术方面,它拥有二十年以上的丰富经验,…...
AI实践与学习1_Milvus向量数据库实践与原理分析
前言 随着NLP预训练模型(大模型)以及多模态研究领域的发展,向量数据库被使用的越来越多。 在XOP亿级题库业务背景下,对于试题召回搜索单单靠着ES集群已经出现性能瓶颈,因此需要预研其他技术方案提高试题搜索召回率。…...
3Dexcite deltgen 2022x 新功能
3DEXCITE DELTAGEN 2022x 现已发布,此次新版发布包含 DELTAGEN 2022x,DELTAGEN MARKETING SUITE 2022x,DELTAGEN XPLORE 2022x,以及软件开发工具包 SDK FOR DELTAGEN 2022x 版本。赶快来获取最新 DG 版本,了解新增内容…...
代码随想录算法训练营第六十天 | LeetCode 84. 柱状图中最大的矩形
代码随想录算法训练营第六十天 | LeetCode 84. 柱状图中最大的矩形 文章链接:柱状图中最大的矩形 视频链接:柱状图中最大的矩形 1. LeetCode 84. 柱状图中最大的矩形 1.1 思路 本题是给一个数组形象得画出图后求矩形的最大面积是多少。本题和42. 接雨水…...
【2023云栖】陈守元:阿里云开源大数据产品年度发布
本文根据 2023 云栖大会演讲实录整理而成,演讲信息如下: 演讲人:陈守元 | 阿里云计算平台事业部开源大数据产品总监 演讲主题:阿里云开源大数据产品年度发布 随着云计算的不断发展,未来数据处理和应用的趋势将围绕C…...
Element UI 禁用数字输入框组件添加鼠标滚动事件
Element UI 禁用数字输入框组件添加鼠标滚动事件 <el-input type"number" mousewheel.native.prevent DOMMouseScroll.native.prevent :min"0" onkeyup"this.valuethis.value.match(/\d\.?\d{0,2}/);"v-model"form.threeYearDevelop…...
担忧CentOS停服?KeyarchOS系统来支撑
担忧CentOS停服?KeyarchOS系统来支撑 近年发生的“微软黑屏门”、“微软操作系统停更”等安全事件,敲响了我国 IT 产业的警钟,建立由我国主导的 IT 产业生态尤为迫切。对此,我国信息技术应用创新行业乘势而起,旨在通过…...
聚观早报 |联想集团Q2财季业绩;小鹏汽车Q3营收
【聚观365】11月17日消息 联想集团Q2财季业绩 小鹏汽车Q3营收 微软发布两款自研AI芯片 FAA批准SpaceX再次发射星际飞船 2023 OPPO开发者大会 联想集团Q2财季业绩 全球数字经济领导企业联想集团公布截至2023年9月30日的2023/24财年第二财季业绩:整体营收达到10…...
SAP ABAP权限控制中常用TCODE
权限控制中的几个TCODE 1.创建新的权限对象并在程序中使用 利用SU21创建权限对象Z_TEST,在程序中检查授权。 检查的代码如下: AUTHORITY-CHECK OBJECT ‘Z_TEST’ID ‘ACTION’ FIELD ‘44′ID ‘BUKRS’ FIELD DUMMY .IF sy-subrc NE 0.MESSAGE e00…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
