Rust 字符串 初步了解

rust 的字符串 。字符串不是复合类型,

String&str

  • String 具有所有权,是存储在堆上的。
  • &str 没有所有权,是对 String 的引用。字符串字面量也是 &str 类型,存储在栈上。

切片(slice)

对于字符串而言,切片就是对字符串一部分的引用。

let s = String::from("hello");

let s1 = &s[0..5]; // 不包含终止索引 hello

创建切片的语法:[开始索引..终止索引]。(该语法是一个右半开区间) 。
切片数据结构:保存开始的位置(指针)和切片的长度。

.. range 序列 语法。

包含第一个字节或最后一个字节时,开始索引或最后索引可以省略。

let s = String::from("hello");

let s1 = &s[..2]; // he

let s2 = &s[2..]; // llo

let s3 = &s[..]; // hello

注意
在使用切片时,需要保证索引落在字符的边界上
因为切片上的索引指的是字节,而不是字符,而且字符串使用的编码是 UTF-8
所以当一个字符占用多个字节时,索引可能不在字符的边界上,导致没有取到完成的字符,出现错误。

字符串切片的类型标识为 &str
所以切片(slice)是一个不可变引用。

其他切片

数组也可以进行切片。
切片是对集合的部分引用,所以所有是集合的类型都可以进行切片。

字符串字面量也是切片,因为类型也是 &str

字符串

字符串与字符:

  • 字符: Unicode 类型,每个字符占用 4 个字节空间。
  • 字符串: UTF-8 类型,每个字符占用的字节数是变化的(1-4).

语言级别上的字符串类型只有 str 。(编程语言提供的原生字符串类型)
标准库中,还有多种不同用途的字符串类型:用的最广的是 String 类型。(额外的字符串处理工具)

strString

  • str 类型是硬编码进可执行文件,无法被修改。
  • String 是一个可增长、可改变且具有所有权的 UTF-8 编码字符串。(&str 也是UTF-8 字符串)

String 与 &str 的转换

&strString

  • String::from("hello")
  • "hello".to_string()

String&str

  • 取引用

Rust 不允许进行字符串索引,因为索引也是按照字节的,可能会落在字符上,导致无法取到完整的字符。

操作字符串

String 的常用方法:

追加(Push)

  • push() 追加 字符
  • push_str() 追加 字符串

在用来的字符串上追加,不会返回新的字符串。
字符串必须是可变的,即必须使用 mut 修饰

let s = String::from("hello");

s.push(','); // hello,

s.push_str(" rust"); // hello, rust

插入(Insert)

  • insert() 插入单个字符 char
  • insert_str() 插入字符串字面量 &str
    需要传入两个参数:
  1. 字符(串)插入位置的索引。(从0开始计数,越界会出现错误)。
  2. 要插入的字符串。

在原来的字符串上修改,字符串必须是 可变 的,必须由 mut 关键字修饰。

fn main() {
	let mut s = String:from("hello");
	
	s.insert(5,','); // hello,
	
	s.insert_str(6," I like"); // hello, I like
}

替换(Replace)

replace

适用于 String&str 类型。

需要两个参数:

  1. 要被替换的字符串。
  2. 新的字符串。
    该方法会替换掉所有的匹配到的字符串。
    该方法返回一个新的字符串,不是操作原来的字符串
fn main() {
	let s = String::from("hello rust");
	let new_s = s.replace("rust", "RUST"); // hello RUST
}
replacen

适用于 String&str 类型。

需要三个参数:

  1. 前两个参数与 replace() 方法一样。
  2. 第三个参数表示替换的个数。
    该方法放回一个新的字符串,不是操作原来的字符串
fn main() {
	let s = String::from("hello rust rust");
	let new_s = s.replacen("rust", "RUST",1); // hello RUST rust
}
replace_range

仅适用于 String 类型。

需要两个参数:

  1. 要替换字符串的范围(Range)。
  2. 新的字符串。
    直接操作原来在字符串,不会返回新的字符串。
    需要使用 mut 关键字修饰
fn main() {
	let s = String::from("hello rust rust");
	s.replace_range(0..1,"H"); // Hello rust rust
}

删除(Delete)

1. pop —— 删除并返回字符串的最后一个字符

直接操作原来的字符串。
存在返回值,返回值是一个 Option 类型,如果字符串为空,则返回 None

fn main() {
	let mut s = String::from("hello");
	let s1 = s.pop(); // hell s1:o
	let s2 = s.pop(); // hel s2:l
}
2. remove —— 删除并返回字符串中指定位置的字符

直接操作原来的字符串。
存在返回值,返回值是删除位置的字符串。

接受一个参数:

  • 表示该字符起始索引位置。

remove() 方法按照字节处理字符串,要求所给的索引落在字符的边界位置。

fn main() {
    let mut string_remove = String::from("测试remove方法");
    println!(
        "string_remove 占 {} 个字节",
        std::mem::size_of_val(string_remove.as_str())
    );
    // 删除第一个汉字
    string_remove.remove(0);
    // 下面代码会发生错误
    // string_remove.remove(1);
    // 直接删除第二个汉字
    // string_remove.remove(3);
    dbg!(string_remove);
}
3. truncate —— 删除字符串中从指定位置到结尾的全部字符

直接操作原来的字符串。
无返回值。
truncate() 方法按照字节来处理字符串,要求参数所给的位置是合法的字符边界。

fn main() {
    let mut string_truncate = String::from("测试truncate");
    string_truncate.truncate(3); // 测
    dbg!(string_truncate);
}
4. clear —— 清空字符串

直接操作原来的字符串。
调用后,删除字符串中的所有字符。

fn main() {
    let mut string_clear = String::from("string clear");
    string_clear.clear();
    dbg!(string_clear);
}

连接(Concatenate)

1. 使用 + 或者 += 连接字符串

右边的参数必须为字符串的切片引用类型(Slice)。

调用 + 时,相当于调用了 std::string 标准库中的 add() 方法,add() 方法的第二个参数是一个引用的类型。
因此,在使用 + 时,必须传递切片引用类型,不能直接传递 String 类型

返回一个新的字符串

fn main() {
    let string_append = String::from("hello ");
    let string_rust = String::from("rust");
    // &string_rust会自动解引用为&str
    let result = string_append + &string_rust;
    let mut result = result + "!"; // `result + "!"` 中的 `result` 是不可变的
    result += "!!!";

    println!("连接字符串 + -> {}", result);
}
2. 使用 format! 连接字符串

适用于 String&str
用法与 print! 的用法类型。

fn main() {
    let s1 = "hello";
    let s2 = String::from("rust");
    let s = format!("{} {}!", s1, s2);
    println!("{}", s);
}

字符串转义

通过转义的方式 \ 输出 ASCII 和 Unicode 字符。

fn main() {
    // 通过 \ + 字符的十六进制表示,转义输出一个字符
    let byte_escape = "I'm writing \x52\x75\x73\x74!";
    println!("What are you doing\x3F (\\x3F means ?) {}", byte_escape);

    // \u 可以输出一个 unicode 字符
    let unicode_codepoint = "\u{211D}";
    let character_name = "\"DOUBLE-STRUCK CAPITAL R\"";

    println!(
        "Unicode character {} (U+211D) is called {}",
        unicode_codepoint, character_name
    );

    // 换行了也会保持之前的字符串格式
    // 使用\忽略换行符
    let long_string = "String literals
                        can span multiple lines.
                        The linebreak and indentation here ->\
                        <- can be escaped too!";
    println!("{}", long_string);
}

不转义的情况:

fn main() {
    println!("{}", "hello \\x52\\x75\\x73\\x74");
    let raw_str = r"Escapes don't work here: \x3F \u{211D}";
    println!("{}", raw_str);

    // 如果字符串包含双引号,可以在开头和结尾加 #
    let quotes = r#"And then I said: "There is no escape!""#;
    println!("{}", quotes);

    // 如果还是有歧义,可以继续增加,没有限制
    let longer_delimiter = r###"A string with "# in it. And even "##!"###;
    println!("{}", longer_delimiter);
}

操作 UTF-8 字符串

字符

Unicode 字符的方式遍历字符串,使用 chars 方法:

for c in "中国人".chars() {
 // c 为 字符串中的每个字符
}

字节

遍历每个字节 ,使用 bytes()

for b in "中国人".bytes() {
	// b 为 字符串的每个字节
}

获取子串

想要准确的从 UTF-8 中获取子串比较困难,标准库并没有提供对应的方法,可以使用第三方库。
推荐 库 utf8_slice

请添加图片描述
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/297906.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nacos与Eureka

一、前言 在构建和管理微服务架构时&#xff0c;选择适当的服务注册中心至关重要。Nacos和Eureka都是微服务体系结构中常用的服务注册和发现工具。本文将探讨它们之间的区别&#xff0c;帮助开发者在选择适合其项目需求的注册中心时做出明智的决策。 二、架构和适用场景 Nacos …

TSConfig 配置(tsconfig.json)

详细总结一下TSConfig 的相关配置项。个人笔记&#xff0c;仅供参考&#xff0c;欢迎批评指正&#xff01; 另外&#xff0c;如果想了解更多ts相关知识&#xff0c;可以参考我的其他笔记&#xff1a; vue3ts开发干货笔记ts相关笔记&#xff08;基础必看&#xff09;ts相关笔记…

【linux笔记1】

目录 【linux笔记1】文件内容的理解用户管理用户管理命令添加用户切换用户修改用户信息删除用户 用户组 【linux笔记1】 文件内容的理解 etc文件夹&#xff1a;etc是拉丁语"et cetera"的缩写&#xff0c;意思是“和其他的”或“等等”。在linux系统中&#xff0c;“…

YOLOv5改进 | 卷积篇 | SAConv轻量化的可切换空洞卷积(附修改后的C3+Bottleneck)

一、本文介绍 本文给大家带来的改进机制是可切换的空洞卷积(Switchable Atrous Convolution, SAC)是一种创新的卷积网络机制,专为增强物体检测和分割任务中的特征提取而设计。SAC的核心思想是在相同的输入特征上应用不同的空洞率进行卷积,并通过特别设计的开关函数来融合这…

sensor 点亮出图后,画面全黑是为什么?

同事在点一个思特威的 sensor sc035hgs&#xff0c;这个 sensor 主要负责数据采集&#xff0c;然后给到后面的 NN&#xff08;神经网络&#xff09;去做处理。 点亮出图后&#xff0c;画面很黑&#xff0c;如下图所示&#xff1a; 因为没拿到板子&#xff0c;只能盲猜&#xf…

[蓝桥 2023 ]三带一

问题描述 小蓝和小桥玩斗地主&#xff0c;小蓝只剩四张牌了&#xff0c;他想知道是否是“三带一”牌型。 所谓“三带一”牌型&#xff0c;即四张手牌中&#xff0c;有三张牌一样&#xff0c;另外一张不与其他牌相同&#xff0c;换种说法&#xff0c;四张手牌经过重新排列后&am…

企业档案集中式管理什么意思?企业档案集中式管理的特点

企业档案集中式管理是指将企业所有的档案资料集中存放、管理和维护的一种方式。在集中式管理中&#xff0c;企业将所有的档案资料集中存放在一个统一的档案中心或档案馆中&#xff0c;通过专门的档案管理人员负责对档案资料进行分类、整理、存储和检索&#xff0c;确保档案资料…

Linux操作系统基础(12):Linux的Shell解释器

1. Shell的介绍 在Linux中&#xff0c;Shell 是一种命令行解释器&#xff0c;它是用户与操作系统内核之间的接口&#xff0c;它负责解释用户输入的命令&#xff0c;并将其转换成系统调用或其他操作系统能够执行的指令。 Shell 提供了一种交互式的方式来与操作系统进行通信&am…

Apache Doris 2.0.2 安装步骤 Centos8

Linux 操作系统版本需求 Linux 系统版本当前系统版本CentOS7.1 及以上CentOS8Ubuntu16.04 及以上- 软件需求 软件版本当前版本Java1.81.8.0_391GCC4.8.2 及以上gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) 1、查看操作系统版本 方法 1&#xff1a;使用命令行 打开终端或…

第九节HarmonyOS 常用基础组件9-TextArea

1、描述 多行文本输入框组件&#xff0c;当输入的文本内容超过组件宽度时会自动换行显示。 2、接口 TextArea(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextAreaController}) 3、参数 参数名 参数类型 必填 描述 placeholder Resour…

通信原理期末复习——计算大题(一)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…

攀登者2 - 华为OD统一考试

OD统一考试 分值: 200分 题解: Java / Python / C++ 题目描述 攀登者喜欢寻找各种地图,并且尝试攀登到最高的山峰。 地图表示为一维数组,数组的索引代表水平位置,数组的元素代表相对海拔高度。其中数组元素0代表地面。 例如:[0,1,2,4,3,1,0,0,1,2,3,1,2,1,0],代表如下…

yiyan.baidu.com生成爬取天气预报,并以xls的形式保存到本地

import requests import xlwt import json# 创建工作簿对象 workbook xlwt.Workbook(encodingutf-8-sig) # 创建工作表对象 worksheet workbook.add_sheet(天气数据)# 设置单元格样式 style xlwt.easyxf(font: bold True;)# 定义列标题 headers [date, city, country, weat…

华为云Stack 8.X流量模型分析(六)

八、基础云专线流量模型分析 ​ 华为官方对云专线定义是&#xff1a;用户数据中心通过运营商的物理专线&#xff08;MPLS/VPN&#xff0c;以太专线&#xff09;访问云内资源&#xff0c;云内资源呈现真实IP&#xff0c;通过设置的专线路由实现三层互通。 ​ 通过云专线直接访…

修改安卓apk设置为安卓主屏幕(launcher)

修改安卓apk 将apk可以设置安卓主屏幕 原理&#xff1a; 将打包好的apk文件进行拆包增加配置文件在重新编译回apk包 需要得相关文件下载 解包 apktool :https://pan.baidu.com/s/1oyCIYak_MHDJCvDbHj_qEA?pwd5j2xdex2jar&#xff1a;https://pan.baidu.com/s/1Nc-0vppVd0G…

MyBatis - 批量更新(update foreach)报错

在使用mybatis执行批量更新(update foreach)数据的时候报错如下&#xff1a; org.springframework.jdbc.BadSqlGrammarException: ### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; c…

jquery图形验证码

效果展示 js图形随机验证码&#xff08;表单验证&#xff09; html代码片段 <form class"formwrap"><div class"item"><input type"text" id"code_input" value"" placeholder"请输入验证码"/>…

OpenHarmony底座升级指南(3.2升级4.0)

前言 本文旨在帮助开发者完成底座升级&#xff0c;文中主要以OpenHarmony 3.2 release 升级至OpenHarmony 4.0 release为模板描述。 一、流程概览&#xff1a; 1.1 准备工作 在准备阶段&#xff0c;需要完整收集所有的定制化修改&#xff0c;明确修改人&#xff1b;并且要将…

JavaScript 基础通关

快速熟悉 JavaScript 的基础语法&#xff0c;比较高级的比如事件放在后面的笔记中。 JavaScript 1. JavaScript 介绍 1.1 JavaScript 基本介绍 JavaScript 是一门运行在客户端&#xff08;浏览器&#xff09;的编程语言&#xff0c;实现人机交互的效果。实现网页特效、表单验…

计算机中的数据运算

放上计算机中的数据的表示方法 计算机中的数据表示方法-CSDN博客 补码的运算&#xff1a; 连同符号位一起相加&#xff0c;符号位产生的进位自然丢掉&#xff0c;这里要特别注意机器数的位数&#xff0c;计算数的位数决定了可以存放的数据的大小&#xff0c;加减产生的数据的…