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]; // helet s2 = &s[2..]; // llolet 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:olet 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会自动解引用为&strlet 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 literalscan 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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java基于ssm的房源管理系统+vue论文

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 vue技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…

【python爬虫开发实战 情感分析】利用爬虫爬取城市评论并对其进行情感分析

&#x1f680;个人主页&#xff1a;为梦而生~ 关注我一起学习吧&#xff01; &#x1f4a1;专栏&#xff1a; python网络爬虫从基础到实战 带你学习爬虫从基础到实战 深度学习带你感受AI的魅力 &#x1f4a1;往期推荐&#xff1a; ⭐️前面比较重要的基础内容&#xff1a; 【Py…

Linux vi/vim 教程

文章目录 【 1. vi/vim 的三种模式 】1.1 命令模式1.2 输入模式1.3 底线命令模式 【 2. 实例 】【 3. vim 的其他命令 】 所有的 Unix Like 系统都会内建 vi 文本编辑器&#xff0c;其他的文本编辑器则不一定会存在。目前我们使用比较多的是 vim 编辑器。vim 从 vi 发展出来&am…

STM32G030C8T6:USART串口通信(中断)

本专栏记录STM32开发各个功能的详细过程&#xff0c;方便自己后续查看&#xff0c;当然也供正在入门STM32单片机的兄弟们参考&#xff1b; 本小节的目标是&#xff0c;系统主频64 MHZ,采用高速外部晶振&#xff0c;通过芯片PB6,PB7 的USART1 口&#xff0c;实现串口通信。 原理…

Docker nginx容器代理播放m3u8视频文件(HLS)

文章目录 Docker Nginx容器代理播放M3U8文件教程获取Nginx Docker镜像设置Nginx配置文件用 ffmpeg 将 MP4 文件转换成 m3u8 文件运行Docker容器测试M3U8流其他问题我用vlc都能播放http://192.168.121.50/forest4kTest.m3u8和http://192.168.121.50/forest4kTest.mp4&#xff0c…

用opencv的DNN模块做Yolov5目标检测(纯干货,源码已上传Github)

最近在微信公众号里看到多篇讲解yolov5在openvino部署做目标检测文章&#xff0c;但是没看到过用opencv的dnn模块做yolov5目标检测的。于是&#xff0c;我就想着编写一套用opencv的dnn模块做yolov5目标检测的程序。在编写这套程序时&#xff0c;遇到的bug和解决办法&#xff0c…

机器学习:手撕 AlphaGo(二)

计算机下围棋的问题描述请见上篇&#xff1a;机器学习&#xff1a;手撕 AlphaGo&#xff08;一&#xff09;-CSDN博客 3. MCTS 算法介绍 MCTS&#xff08;Monte Carlo Tree Search&#xff09; 算法的中文名称叫做蒙特卡洛树搜 索。第一次接触这个算法时&#xff0c;便惊叹于它…

Java 说一下 synchronized 底层实现原理?

Java 说一下 synchronized 底层实现原理&#xff1f; synchronized 是 Java 中用于实现同步的关键字&#xff0c;它保证了多个线程对共享资源的互斥访问。底层实现涉及到对象头的 Mark Word 和锁升级过程。 synchronized 可以用于方法上或代码块上&#xff0c;分别对应于方法…

Ubuntu 本地部署 ChatGPT-Next-Web

Ubuntu 本地部署 ChatGPT-Next-Web 文章目录 Ubuntu 本地部署 ChatGPT-Next-Web ChatGPT-Next-Web 项目地址&#xff1a;https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web 本文主要演示如何在 Ubuntu 本地&#xff08;默认是端口 3000&#xff09;部署 ChatGPT-Next-Web&am…

使用 Docker Compose 部署 Docker Registry

在内网环境中&#xff0c;我们期望能够在本地共享镜像。为了解决这一问题&#xff0c;Docker Registry成为了我们的救星。Docker Registry是一个用于存储和管理Docker镜像的开源工具。通过在本地部署Docker Registry&#xff0c;您可以轻松地构建、存储和分享自己的Docker镜像。…

[SwiftUI]工程最低适配iOS13

问题&#xff1a; 新建工程&#xff0c;选择最低支持iOS13报错&#xff1a; main() is only available in iOS 14.0 or newer Scene is only available in iOS 14.0 or newer WindowGroup is only available in iOS 14.0 or newer 解决&#xff1a; 注释掉上面代码&#x…

分布式系统架构设计之分布式缓存技术选型

一、概述 随着互联网业务的快速发展&#xff0c;分布式系统已经成为了解决大规模并发请求、高可用性、可扩展性等问题的重要手段。在分布式系统中&#xff0c;缓存作为提高系统性能的关键技术&#xff0c;能够显著降低数据库负载、减少网络延迟、提高数据访问速度。当面对大量…

jetson orin配置yolov8运行环境

配置yolov8环境 当前jetpack版本为5.1.1&#xff0c;对应的torch为1.14.0版本&#xff0c;torchvision版本为0.14.1&#xff0c;CUDA版本为11.4.315.opencv with cuda 版本4.5.4&#xff0c;tensorrt版本5.1.1。pytorch1.12.0 torchvision0.13.0 具体对应关系查看https://foru…

eureka注册列表 某服务出现多个服务实例

最近文件导出功能偶发成功&#xff0c;大部分情况都失败&#xff0c;开始以为接口被拦截&#xff0c;gateway服务没有接口调用日志&#xff0c;发现测试环境可以&#xff0c;正式环境功能无法正常使用。 偶然看到注册中心如下 发现file服务有3个实例&#xff0c;调用接口将错误…

基于单片机的农田灌溉系统(论文+源码)

1.系统设计 本系统主要实现如下目标&#xff1a; 1&#xff0e;可以实时监测土壤湿度&#xff1b; 2&#xff0e;土壤湿度太低时&#xff0c;进行浇水操作&#xff1b; 3&#xff0e;可以按键设置湿度的触发阈值&#xff1b; 4. 可以实现远程操控 5&#xff0e;可以实现手…

Vue中使用Element UI的Table组件实现嵌套表格(最简单示例)

以下是一个简单的示例代码&#xff0c;演示如何在Vue中使用Element UI的Table组件实现嵌套表格&#xff1a; html <template><div><el-table :data"tableData" style"width: 100%"><el-table-column prop"name" label&quo…

安卓作业002 - 用户登录窗口

文章目录 安卓作业002 - 用户登录窗口一、界面设计思路二、涉及的知识点概览三、界面实现步骤四、启动应用查看结果五、任务完成总结安卓作业002 - 用户登录窗口 利用到布局嵌套实现复杂界面居中对齐,利用线性布局的gravity属性标签、编辑框、按钮三种控件编辑框的提示信息,利…

实习记录留存

0.前提 实习结束了我留个档方便以后查看 校内实习玩具_哔哩哔哩_bilibili 不如这个爽 带兄弟们飙车_哔哩哔哩_bilibili

第九节HarmonyOS 常用基础组件6-progress

1、描述 进度条组件用于显示内容加载或操作处理等进度。 2、接口 Progress(options:{value:number,total?Number, type?:ProgressType}) 参数&#xff1a; 参数名 参数类型 必填 参数描述 value number 是 指定当前进度值。设置小于0的数值时置为0&#xff0c;设置…

各银行小微企业信贷相关产品和机器学习建模案例

各银行小微企业贷款业务 互联网的时代&#xff0c;大量新信息技术的涌现和网络的无处不在&#xff0c;想要抢占这片金融天地&#xff0c;必须重视小微金融业务&#xff0c;小微企业是一直具有重大潜力的客户&#xff0c;商业银行、消金公司发展小微信贷业务可以拓宽自身客户群…