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

【Rust】字符串,看这篇就够了

这节课我们把字符串单独拿出来讲,是因为字符串太常见了,甚至有些应用的主要工作就是处理字符串。比如 Web 开发、解析器等。而 Rust 里的字符串内容相比于其他语言来说还要多一些。是否熟练掌握 Rust 的字符串的使用,对 Rust 代码开发效率有很大影响,所以这节课我们就来重点攻克它。
可怕的字符串?
我们在 Rust 里常常会见到一些字符串相关的内容,比如下面这些。

String, &String, 
str, &str, &'static str
[u8], &[u8], &[u8; N], Vec<u8>
as_str(), as_bytes()
OsStr, OsString
Path, PathBuf
CStr, CString

首先,我们来看 C 语言里的字符串。图里显示,C 中的字符串统一叫做 char *,这确实很简洁,相当于是统一的抽象。但是这个统一的抽象也付出了代价,就是丢失了很多额外的信息。
为什么会这样呢?我们从计算机结构说起。我们都知道,计算机 CPU 执行的指令都是二进制序列,所有语言写的程序最后执行时都会归结为二进制序列来执行。但是为什么不直接写二进制打孔开发,而是出现了几百上千种计算机语言呢?没错,就是因为抽象。
抽象是用来解决现实问题建模的工具。在 Rust 里也一样,之所以 Rust 有那么多看上去都是字符串的类型,就是因为 Rust 把字符串在各种场景下的使用给模型化、抽象化了。相比 C 语言的 char *,多了建模的过程,在这个模型里面多了很多额外的信息。
下面我们就来看看前面提到的那些字符串类型各自有什么具体含义。
不同类型的字符串

示例:
fn main() {let s1: &'static str = "More Powerful,Choose Rust"; let s2: String = s1.to_string(); let s3: &String = &s2;let s4: &str = &s2[..];let s5: &str = &s2[..6];
}

上述示例中,s1、s2、s3、s4、s5 看起来好像是 4 种不同类型的字符串表示。为了让你更容易理解,我画出它们在内存中的结构图。
在这里插入图片描述
我来详细解释一下这张图片的意思。
“More Powerful,Choose Rust” 这个用双引号括起来的部分是字符串的字面量,存放在静态数据区。而 s1 是指向静态数据区中的这个字符串的切片引用,形式是 &'static str,这是静态数据区中的字符串的表示方法。
通过执行 s1.to_string(),Rust 将静态数据区中的字符串字面量拷贝了一份到堆内存中,通过 s2 指向,s2 具有这个堆内存字符串的所有权,String 在 Rust 中就代表具有所有权的字符串。
s3 就是对 s2 的不可变引用,因此类型为 &String。
s4 是对 s2 的切片引用,类型是 &str。切片就是一块连续内存的某种视图,它可以提取目标对象的全部或一部分。这里 s4 就是取的目标对象字符串的全部。
s5 是对 s2 的另一个切片引用,类型也是 &str。与 s4 不同的是,s5 是 s2 的部分视图。具体来说,就是 “I am a” 这一部分。
相信你通过上面的例子对这几种不同类型的字符串已经有了一个简单直观的认识了,下面我来给你详细解释下。
String 是字符串的所有权形式,常常在堆中分配。String 字符串的内容大小是可以动态变化的。而 str 是字符串的切片类型,通常以切片引用 &str 形式出现,是字符串的视图的借用形式。
字符串字面量默认会存放在静态数据区里,而静态数据区中的字符串总是贯穿程序运行的整个生命期,直到程序结束的时候才会被释放。因此不需要某一个变量对其拥有所有权,也没有哪个变量能够拥有这个字符串的所有权(也就是这个资源的分配责任)。因此对于字符串字面量这种数据类型,我们只能拿到它的借用形式 &'static str。这里 'static 表示这个引用可以贯穿整个程序的生命期,直到这个程序运行结束。
&String 仅仅是对 String 类型的字符串的普通引用。
对 String 做字符串切片操作后,可以得到 &str。这里这个 &str 就是指向由 String 管理的内存资源的切片引用,是目标字符串资源的借用形式,不会再把字符串内容复制一份。
从上面的图示里可以看到,&str 既可以引用堆中的字符串,也可以引用静态数据区中的字符串(&'static str 是 &str 的一种特殊形式)。其实内存本来就是一个线性空间,一个指针(引用是指针的一种)理论上来说可以指向这个线性空间中的任何地址。
&str 也可转换为 String。你可以通过示例,看一下它们之间是如何转换的。
let s: String = “More Powerful,Choose Rust”.to_string();
let a_slice: &str = &s[…];
let another_String: String = a_slice.to_string();
切片
上面提到了切片,这里我再补充一点关于切片(slice)的背景知识。切片是一段连续内存的一个视图(view),在 Rust 中由 [T] 表示,T 为元素类型。这个视图可以是这块连续内存的全部或一部分。切片一般通过切片的引用来访问,你可以看一下我给出的这个字符串示例。
let s = String::from(“abcdefg”);
let s1 = &s[…]; // s1 内容是 “abcdefg”
let s2 = &s[0…4]; // s2 内容是 “abcd”
let s3 = &s[2…5]; // s3 内容是 “cde”
上面示例中,s 是堆内存中所有权型字符串类型。s1 作为 s 的一个切片引用,它也指向堆内存中那个字符串的头部,表示 s 的完整内容。s2 与 s1 指向的堆内存地址是相同的,但是内容不同,s2 是 “abcd”,而 s1 是 “abcdefg”。s3 则是 s 的中间位置的一段切片引用,内容是 “cde”。s3 指向的地址与 s、s1、s2 不同。
我画了一张图来表示它们之间的关系。

相关文章:

【Rust】字符串,看这篇就够了

这节课我们把字符串单独拿出来讲&#xff0c;是因为字符串太常见了&#xff0c;甚至有些应用的主要工作就是处理字符串。比如 Web 开发、解析器等。而 Rust 里的字符串内容相比于其他语言来说还要多一些。是否熟练掌握 Rust 的字符串的使用&#xff0c;对 Rust 代码开发效率有很…...

单片机和 ARM 的区别

单片机和 ARM 在功能和使用上有一些区别&#xff0c;因此哪个更好用取决于具体的需求和场景。 单片机是一种集成了微处理器、存储器和外设接口的集成电路芯片&#xff0c;通常具有体积小、功耗低、可靠性高、成本低等特点。单片机广 泛应用于各种领域&#xff0c;如智能仪表、工…...

JavaScript从入门到精通系列第三十一篇:详解JavaScript中的字符串和正则表达式相关的方法

文章目录 知识回顾 1&#xff1a;概念回顾 2&#xff1a;正则表达式字面量 一&#xff1a;字符串中正则表达式方法 1&#xff1a;split 2&#xff1a;search 3&#xff1a;match 4&#xff1a;replace 知识回顾 1&#xff1a;概念回顾 正则表达式用于定义一些字符串的…...

23、数据结构/查找相关练习20240205

一、请编程实现哈希表的创建存储数组{12,24,234,234,23,234,23},输入key查找的值&#xff0c;实现查找功能。 代码&#xff1a; #include<stdlib.h> #include<string.h> #include<stdio.h> #include<math.h> typedef struct Node {int data;struct n…...

【VSTO开发-WPS】下调试

重点2步&#xff1a; 1、注册表添加 Windows Registry Editor Version 5.00[HKEY_CURRENT_USER\Software\kingsoft\Office\WPP\AddinsWL] "项目名称"""2、visual studio 运行后&#xff0c;要选中附加到调试&#xff0c;并指定启动项目。 如PPT输入WPP搜…...

git 的基本概念

当使用Git时&#xff0c;一些基本概念包括&#xff1a; 1. **仓库&#xff08;Repository&#xff09;&#xff1a;** 存储项目文件和版本历史的地方。可以是本地仓库&#xff08;在你的计算机上&#xff09;或远程仓库&#xff08;在服务器上&#xff09;。 2. **提交&#…...

《统计学习方法:李航》笔记 从原理到实现(基于python)-- 第6章 逻辑斯谛回归与最大熵模型(1)6.1 逻辑斯谛回归模型

文章目录 第6章 逻辑斯谛回归与最大熵模型6.1 逻辑斯谛回归模型6.1.1 逻辑斯谛分布6.1.2 二项逻辑斯谛回归模型6.1.3 模型参数估计6.1.4 多项逻辑斯谛回归 《统计学习方法&#xff1a;李航》笔记 从原理到实现&#xff08;基于python&#xff09;-- 第3章 k邻近邻法 《统计学习…...

Go 中如何检查文件是否存在?可能产生竞态条件?

嗨&#xff0c;大家好&#xff01;本文是系列文章 Go 技巧第十三篇&#xff0c;系列文章查看&#xff1a;Go 语言技巧。 Go 中如何检查文件是否存在呢&#xff1f; 如果你用的是 Python&#xff0c;可通过标准库中 os.path.exists 函数实现。遗憾的是&#xff0c;Go 标准库没有…...

红日靶场1搭建渗透

环境搭建 下载好镜像文件并解压&#xff0c;启动vmware 这里我用自己的win7 sp1虚拟机作为攻击机&#xff0c;设置为双网卡NAT&#xff0c;vm2 其中用ipconfig查看攻击机ip地址 设置win7 x64为双网卡&#xff0c;vm1&#xff0c;vm2 设置win08单网卡vm1&#xff0c;win2k3为单…...

ChatGPT之搭建API代理服务

简介 一行Docker命令部署的 OpenAI/GPT API代理&#xff0c;支持SSE流式返回、腾讯云函数 。 项目地址&#xff1a;https://github.com/easychen/openai-api-proxy 这个项目可以自行搭建 OpenAI API 代理服务器工具&#xff0c;该项目是代理的服务器端&#xff0c;不是客户端。…...

Kotlin手记(一):基础大杂烩

Kotlin简介 2011年7月&#xff0c;JetBrains推出Kotlin项目&#xff0c;这是一个面向JVM的新语言 2012年2月&#xff0c;JetBrains以Apache 2许可证开源此项目。 2016年2月15日&#xff0c;Kotlin v1.0发布&#xff0c;这被认为是第一个官方稳定版本。 在Google I/O 2017中&am…...

redis源码之:集群创建与节点通信(2)

在上一篇redis源码之&#xff1a;集群创建与节点通信&#xff08;1&#xff09;我们可知&#xff0c;在集群中&#xff0c;cluster节点之间&#xff0c;通过meet将对方加入到本方的cluster->nodes列表中&#xff0c;并在后续过程中&#xff0c;不断通过clusterSendPing发送p…...

2024.2.5 寒假训练记录(19)

文章目录 牛客 寒假集训2A Tokitsukaze and Bracelet牛客 寒假集训2B Tokitsukaze and Cats牛客 寒假集训2D Tokitsukaze and Slash Draw牛客 寒假集训2E Tokitsukaze and Eliminate (easy)牛客 寒假集训2F Tokitsukaze and Eliminate (hard)牛客 寒假集训2I Tokitsukaze and S…...

游戏服务器租赁多少钱一台?26元,服不服?

游戏服务器租用多少钱一年&#xff1f;1个月游戏服务器费用多少&#xff1f;阿里云游戏服务器26元1个月、腾讯云游戏服务器32元&#xff0c;游戏服务器配置从4核16G、4核32G、8核32G、16核64G等配置可选&#xff0c;可以选择轻量应用服务器和云服务器&#xff0c;阿腾云atengyu…...

wpf 引入本项目的图片以及引入其他项目的图像资源区别及使用方法

在WPF项目中引入本项目的图片和引入其他项目的图像资源&#xff0c;两者的主要区别在于资源的位置以及如何通过URI引用它们。以下是详细说明及使用方法&#xff1a; ​ 一、引入本项目的图片资源&#xff1a; 将图片文件&#xff08;如PNG, JPG等&#xff09;放入你的WPF项目…...

jsp页面,让alert弹出信息换行显示

第一种方式&#xff1a;后端拼接上换行符前端显示 1&#xff0c;java后端将信息封装成字符串时&#xff0c;在需要换行的地方拼接上一个换行符&#xff0c; 显示在HTML中的换行&#xff0c;通常需要用<br>标签替代\n&#xff0c;如下&#xff1a; String javaString &…...

【IC设计】Windows下基于IDEA的Chisel环境安装教程(图文并茂)

Chisel环境安装教程 第一步 安装jdk&#xff0c;配置环境变量第二步 安装sbt&#xff0c;不用配置环境变量第三步 安装idea社区版第四步 离线安装scala的idea插件第五步 配置sbt换源1.切换目录2.创建repositories文件3.配置sbtconfig.txt文件 第六步 使用chisel-tutorial工程运…...

IF=82.9!高分文献解读|吉西他滨联合顺铂化疗激活肿瘤免疫新机制

鼻咽癌&#xff08;nasopharyngeal carcinoma, NPC&#xff09;是一种发生于鼻咽部上皮细胞的恶性肿瘤&#xff0c;且高发于中国。吉西他滨联合顺铂&#xff08;GP&#xff09;化疗作为鼻咽癌的一种全球标准治疗方案&#xff0c;然而治疗的具体机制目前尚不清楚。中山大学肿瘤防…...

【QT+QGIS跨平台编译】之二十八:【Protobuf+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、Protobuf介绍二、文件下载三、文件分析四、pro文件4.1 libprotobuf4.2 libprotobuf-lite4.3 libprotoc4.4 protocApp五、编译实践一、Protobuf介绍 Protocol Buffers(简称 Protobuf)是由 Google 开发的一种数据序列化协议,就像 XML 或 JSON 一样,但是它更小、…...

代码解析:list.stream().filter(Objects::nonNull).collect(Collectors.toList())

这段Java代码是使用了Java 8引入的流(Stream) API来处理集合&#xff08;比如List&#xff09;。这个特定的例子展示了如何从一个列表中过滤掉所有的null值&#xff0c;并返回一个新的列表&#xff0c;其中不包含任何null元素。下面是对这段代码的逐步解析&#xff1a; 代码解…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...