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

【Rust自学】8.3. String类型 Pt.1:字符串的创建、更新与拼接

8.3.0. 本章内容

第八章主要讲的是Rust中常见的集合。Rust中提供了很多集合类型的数据结构,这些集合可以包含很多值。但是第八章所讲的集合与数组和元组有所不同。

第八章中的集合是存储在堆内存上而非栈内存上的,这也意味着这些集合的数据大小无需在编译时就确定,在运行时它们可以动态地变大或变小。

本章主要会讲三种集合:Vector、String(本文) 和HashMap

喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)

8.3.1. String对开发者造成的困扰

Rust开发者(尤其是新手)会经常被字符串困扰,原因如下:

  • Rust倾向于暴露可能的错误
  • 字符串数据结构复杂
  • Rust字符串使用了UTF-8编码

8.3.2. 字符串是什么

字符串是基于字节(Byte)的集合,并且它提供了一些方法,这些方法能将字节解析为文本。

在Rust的核心语言层面,只有一个字符串类型——字符串切片str,通常是以借用的情况出现的,也就是&str

字符串切片是对存储在其他地方、utf-8编码的字符串的引用。例如字符串字面值就是直接存储在Rust的二进制文件中,所以它也是一种字符串切片。

String类型来自于标准库,而不是核心语言。它是一种可增长、可修改、可拥有(获得所有权)的类型,它也采用utf-8编码。

8.3.3. 字符串到底是指谁?

通常说的字符串就是指String&str这两种类型,而不是其中的一种。这两种类型在标准库里都用的非常频繁,也都是使用了utf-8编码,但这里主要还是讲String类型,因为它更复杂。

8.3.4. 其他的字符串类型

Rust标准库还提供了其他的字符串类型,例如:OsStringOsStrCStringCStr。但是注意这些类型都是以String或者是Str结尾,这就跟之前讲的String和字符串切片这两种类型的写法又一些关系。

通常来说,以String结尾的字符串类型是可以获得所有权的,以Str结尾的类型通常是指可借用 的。

这些不同的字符串类型可以存储不同编码的文本或是在内存中以不同的形式展现(布局不一样)。

某些library crate针对字符串可提供更多的选项,这里就不介绍了。

8.3.5. 创建一个新的字符串(String)

由于String类型的本质是字节的集合,所以很多Vec<T>的操作都可以用于String

String::new()可以用来创建一个空的字符串。看个例子:

fn main(){
	let mut s = String::new();
}

但是一般而言都是使用初始值来创建String。这个时候就可以使用to_string方法来创建String,这个方法可用于实现了Display trait的类型,包括字符串字面值。如下例:

fn main() {  
    let data = "wjq";  
    let s = data.to_string();  
    let s1 = "wjq".to_string();  
}

data是一个字符串字面值,而使用to_string这个方法把它转为String类型,存储在s里。或者也可以直接写字符串字面值,然后写.to_string(),也就是给s1赋值的操作。这两个操作是同样的效果。

to_string也不是唯一的方法,第二种方法是使用String::from函数。如下例:

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

这个函数和to_string方法的效果是一样的。

由于字符串它用的地方非常多,所以Rust提供了很多不同的通用API供我们选择,有些函数可能看着很多余,但实际上它们都有各自的用处。而在实际编码时可以根据喜好来选择。

8.3.6. 更新String

之前提到了,String类型的大小是可以增减的,其本质是字节的集合,里面的内容也可以修改,它的操作就跟Vector一样,此外还可以对String进行拼接。

1. push_str()

首先讲push_str(),它是一个把字符串切片附加到String的方法。如下例:

fn main() {  
    let mut s = String::from("6657");  
    s.push_str("up up");  
    println!("{}", s);  
}

输出:

6657up up

push_str的签名是push_str(&mut self, string:&str),它的参数类型是借用的这个字符串切片,而字符串字面值就是切片,所以"up up"可以传进去,并且这个方法不会获得参数的所有权,所以传进去的参数不会失效,还能继续使用。

2. push

第二个方法叫push(),它能把单个字符附加到String里面。如下例:

fn main() {  
    let mut s = String::from("665");  
    s.push('7');  
    println!("{}", s);  
}

注意,字符得使用单引号。

输出:

6657

3.+

Rust允许使用+来拼接字符串。如下例:

fn main() {  
    let s1 = String::from("6657");  
    let s2 = String::from("up up");  
    let s3 = s1 + &s2;  
    println!("{}", s3);  
}

注意:加号前是字符串类型,加号后得是字符串切片类型。

但在这个例子中实际上加号后的数据类型是&String而不是&str。这时因为这里Rust使用了解引用强制转换(deref coercion) 的功能,把&String类型强制转换为&str

当然,因为s2传进去的是引用,所以s2在拼接后是仍然有效的,而s1是把本身的所有权交给了s3,所以s1在拼接后就无效了。

输出:

6657up up

4. format!

format!这个宏可以更加灵活的拼接字符串。如下例:

fn main() {  
    let s1 = String::from("cn");  
    let s2 = String::from("Niko");  
    let s3 = String::from("fan club");  
    let s = format!("{} {} {}", s1, s2, s3);  
    println!("{}", s);  
}

使用占位符来代替变量,这点和println!很像,println!是把结果进行输出,而format!则是返回了拼接好的字符串。

输出:

cn Niko fan club

当然使用+也能实现一样的效果,只不过写起来稍微麻烦一些:

fn main() {  
    let s1 = String::from("cn");  
    let s2 = String::from("Niko");  
    let s3 = String::from("fan club");  
    let s = s1 + " " + &s2 + " " + &s3;  
    println!("{}", s);  
}

format!最好的一点是它不会取得任何参数的所有权,这些参数在后续都可以继续使用。


http://www.kler.cn/a/463122.html

相关文章:

  • 电子应用设计方案85:智能 AI门前柜系统设计
  • Docker入门常用命令总结
  • Java项目实战II基于微信小程序的家庭大厨(开发文档+数据库+源码)
  • 库伦值自动化功耗测试工具
  • 【Vue3】h、ref:vue3的两个新特性(重要)-h和ref
  • 【Patroni官方文档】介绍与目录
  • Sentinel 介绍与使用指南:构建高可用、可靠的微服务架构
  • 大数据面试笔试宝典之大数据运维面试
  • 【文献精读笔记】Explainability for Large Language Models: A Survey (大语言模型的可解释性综述)(二)
  • 【Spring】Spring DI(依赖注入)详解—集合类型的注入——List、Set、Map的配置与注入
  • linux tar 文件解压压缩
  • 【人工智能】Python实现时序数据预测:ARIMA与LSTM的对比
  • Quartus DMA IP示例使用说明--MM接口
  • Spring实现输出带动态标签的日志
  • 【非关系型数据库Redis 】 入门
  • 32单片机从入门到精通之开发环境——库文件(六)
  • 三层交换机的原理详解
  • Keil中的gcc
  • 用PicGo向Github图床上传图片,然后通过markdown语言显示图片
  • Qt天气预报系统设计界面布局第四部分左边
  • 基于单片机中药存放环境监测系统的实现
  • 第三讲 比特币的早期发展
  • overscroll-behavior-解决H5在ios上过度滚动的默认行为
  • 茶叶连锁店管理系统(源码+文档+部署+讲解)
  • MySQL三大日志(binlog、redo log和undo log)详解
  • 职场常用Excel基础01-数据验证