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.hqwc.cn/news/324875.html

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

相关文章

开发个小破软件——网址导航,解压就能用

网址导航 网站导航也称链接目录&#xff0c;将网站地址或系统地址分类&#xff0c;以列表、图文等形式呈现&#xff0c;帮助快速找到需要的地址。 应用场景 高效查找&#xff1a;网址导航是很好的入口&#xff0c;通过分类清晰的网站推荐&#xff0c;可以迅速访问网站资源。…

【Python学习】2024PyCharm插件推荐

目录 【Python学习】2024PyCharm插件推荐 1. Key Promoter X2.Rainbow CSV3.Markdown4.Rainbow Brackets5.Indent Rainbow6.Regex Tester7.Regex Tester8.Background Image Plus9.Material Theme UI10. Chinese 汉化插件参考 文章所属专区 Python学习 1. Key Promoter X 方便…

超维空间M1无人机使用说明书——31、基于模板匹配的物体识别功能

引言&#xff1a;ROS提供的物体识别功能包find_object_2d&#xff0c;该功能包用起来相对简单&#xff0c;只需要简单进行模板匹配即可。需要接显示器进行模板训练&#xff0c;远程比较卡&#xff0c;不建议 一、功能包find_object_2d简介 ROS的优点之一是有大量可以在应用程…

spring-boot-maven插件repackage(goal)的那些事

前言&#xff1a;在打包Springboot项目成jar包时需要在pom.xml使用spring-boot-maven-plugin来增加Maven功能&#xff0c;在我的上一篇博客<<Maven生命周期和插件的那些事&#xff08;2021版&#xff09;>>中已经介绍过Maven和插件的关系&#xff0c;在此不再赘述&…

黑马程序员SpringBoot2-运维实用篇

视频连接&#xff1a;运维实用篇-51-工程打包与运行_哔哩哔哩_bilibili 打包与运行 程序打包与运行&#xff08;Windows&#xff09; 可执行jar包目录结构 左上角的结构是没有插件打包后的结构&#xff0c;左下是安装插件后的结构。 jar包描述文件&#xff08;MANIFEST.MF&a…

2023高级人工智能期末总结

1、人工智能概念的一般描述 人工智能是那些与人的思维相关的活动&#xff0c;诸如决策、问题求解和学习等的自动化&#xff1b; 人工智能是一种计算机能够思维&#xff0c;使机器具有智力的激动人心的新尝试&#xff1b; 人工智能是研究如何让计算机做现阶段只有人才能做得好的…

小型企业网设计-课设实验-爆款实验

可以按照我的配置依次配置&#xff0c;成品打包文件&#xff0c;请&#xff1a;Ensp888 <Huawei>sys Enter system view, return user view with CtrlZ. [Huawei]un in en Info: Information center is disabled. [Huawei]# [Huawei]sysname SW5 [SW5]# [SW5]vlan batch…

Linux GDB 调试

文章目录 一、Qemu二、Gdbvscode 调试 三、RootFs 一、Qemu qemu 虚拟机 Linux内核学习 Linux 内核调试 一&#xff1a;概述 Linux 内核调试 二&#xff1a;ubuntu20.04安装qemu Linux 内核调试 三&#xff1a;《QEMU ARM guest support》翻译 Linux 内核调试 四&#xff1a;…

应用层网络协议

tags: [“计算机网络”] descripution: “学习应用层的一些常用协议” 网络协议&#xff1a;约定的信息传输的格式&#xff0c;如几个字节是消息头、消息头记录什么信息之类的&#xff1b;c/s架构&#xff1a;不一定是两台计算机&#xff0c;而是两个应用、两个端口工具&#…

苹果系统盘制作

苹果系统盘制作 macOS做系统&#xff0c;有一个macOS系统盘会方便很多&#xff0c;会比联网安装系统快捷不少 准备工作&#xff1a; 1.下载好系统镜像文件 macOS系统下载参考 2.一个U盘&#xff08;最好不低于16G&#xff0c;不要太小了&#xff0c;现在的镜像文件越来约大了…

61.网游逆向分析与插件开发-游戏增加自动化助手接口-游戏红字公告功能的逆向分析

内容来源于&#xff1a;易道云信息技术研究院VIP课 上一节内容&#xff1a;游戏公告功能的逆向分析与测试-CSDN博客 码云地址&#xff08;master分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;63e04cc40f649d10ba2f4f…

线程同步及互斥锁

一、线程同步 1. 线程同步&#xff1a;即当有一个线程在对内存进行操作时&#xff0c;其他线程都不可以对这个内存地址进 行操作&#xff0c;直到该线程完成操作&#xff0c;其他线程才能对该内存地址进行操作&#xff0c;而其他线程则处 于等待状态。 2. 临界区是指访问某…