青少年编程与数学 02-019 Rust 编程基础 07课题、字符串

青少年编程与数学 02-019 Rust 编程基础 07课题、字符串

  • [一、`String` 类型](#一、String 类型)
  • [二、字符串切片 `&str`](#二、字符串切片 &str)
    • 特点
    • [创建 `&str`](#创建 &str)
    • 常见操作
      • [1. 字符串方法](#1. 字符串方法)
      • [2. 模式匹配](#2. 模式匹配)
      • [3. 字符串的内存管理](#3. 字符串的内存管理)
      • [4. 字符串的注意事项](#4. 字符串的注意事项)
      • [5. 示例代码](#5. 示例代码)
  • 三、综合示例
  • 总结

课题摘要:

在 Rust 中,字符串是处理文本数据的基本类型之一。Rust 提供了多种字符串类型,其中最常用的是 String 和字符串切片 &str。它们在内存管理和使用场景上各有特点。本文是关于 Rust 字符串类型的详细解析。
关键词:字符串


一、String 类型

String 是 Rust 中的动态字符串类型,它是一个可增长、可变的 UTF-8 编码字符串。String 在堆上分配内存,支持动态扩展和修改。

特点

  • 动态大小:String 的大小可以在运行时动态调整。
  • UTF-8 编码:存储的是 UTF-8 编码的文本数据。
  • 所有权:String 遵循 Rust 的所有权规则,每次移动或复制时需要考虑所有权转移。
  • 可变性:可以通过方法动态修改字符串的内容。

创建 String

rust 复制代码
let s = String::new(); // 创建一个空的 String
let s = String::from("Hello"); // 从字符串字面量创建
let s = "Hello".to_string(); // 使用 to_string 方法创建

常见操作

  • 添加内容

    rust 复制代码
    let mut s = String::from("Hello");
    s.push_str(", World!"); // 添加字符串
    s.push('!'); // 添加单个字符
  • 拼接字符串

    rust 复制代码
    let s1 = String::from("Hello");
    let s2 = String::from(", World!");
    let s3 = s1 + &s2; // s1 被移动,s2 的内容被拼接到 s1
  • 迭代字符

    rust 复制代码
    for c in "Hello".chars() {
        println!("{}", c); // 按字符迭代
    }
  • 访问子字符串

    rust 复制代码
    let s = "Hello";
    let hello = &s[0..5]; // 获取子字符串,注意边界检查

二、字符串切片 &str

字符串切片 &str 是对字符串的不可变引用,它是一个不可变的字符串片段。&str 是 Rust 中的原始字符串类型,通常用于字符串字面量或字符串的不可变视图。

特点

  • 不可变:&str 是不可变的,不能直接修改其内容。
  • 借用:&str 是对字符串的借用,不拥有数据的所有权。
  • 性能高效:由于不涉及所有权转移,&str 的使用通常比 String 更高效。

创建 &str

rust 复制代码
let s: &str = "Hello"; // 字符串字面量是 &str 类型
let s = String::from("Hello");
let slice: &str = &s[0..5]; // 从 String 创建字符串切片

常见操作

1. 字符串方法

rust 复制代码
let s = "Hello";
println!("{}", s.len()); // 获取字节长度
println!("{}", s.chars().count()); // 获取字符数量

2. 模式匹配

rust 复制代码
let s = "Hello";
if let Some(index) = s.find('e') {
    println!("找到字符 'e' 的位置:{}", index);
}

3. 字符串的内存管理

  • String 的内存分配

    • String 在堆上分配内存,初始容量为 0。
    • 当向 String 中添加内容时,如果超出当前容量,Rust 会自动分配更多内存,并将旧数据复制到新的内存中。
    • 可以通过 with_capacity 方法预先分配足够的容量,以减少内存重新分配的次数。
  • 字符串切片的内存管理

    • &str 是对字符串的引用,不涉及内存分配。
    • 字符串切片的生命周期取决于它所引用的字符串。

4. 字符串的注意事项

  • UTF-8 编码:Rust 的字符串是 UTF-8 编码的,这意味着一个字符可能占用多个字节。因此,直接通过索引访问字符可能会导致错误。
  • 字符串拼接:字符串拼接时需要注意所有权和借用规则。例如,+ 操作符会移动左侧的字符串。
  • 性能优化:如果需要频繁修改字符串,建议使用 String;如果只需要读取字符串,使用 &str 更高效。

5. 示例代码

以下是一个完整的示例代码,展示了 String&str 的常见用法:

rust 复制代码
fn main() {
    // 创建 String
    let mut s = String::from("Hello");
    s.push_str(", World!");
    println!("{}", s); // 输出:Hello, World!

    // 创建字符串切片
    let slice: &str = &s[0..5];
    println!("{}", slice); // 输出:Hello

    // 字符串拼接
    let s1 = String::from("Hello");
    let s2 = String::from(", World!");
    let s3 = s1 + &s2; // s1 被移动
    println!("{}", s3); // 输出:Hello, World!

    // 迭代字符
    for c in "Hello".chars() {
        println!("{}", c); // 按字符迭代
    }
}

三、综合示例

以下是一个综合示例代码,全面展示了 Rust 中字符串类型(String)和字符串切片(&str)的定义及常见操作:

rust 复制代码
fn main() {
    // === String 的定义及常见操作 ===

    // 创建一个空的 String
    let mut s1 = String::new();
    println!("创建一个空的 String: {:?}", s1);

    // 从字符串字面量创建 String
    let s2 = String::from("Hello");
    println!("从字符串字面量创建 String: {}", s2);

    // 使用 to_string 方法从字符串字面量创建 String
    let s3 = "Hello".to_string();
    println!("使用 to_string 方法创建 String: {}", s3);

    // 添加内容
    s1.push_str(", World!");
    println!("向 s1 添加字符串: {}", s1);

    s1.push('!');
    println!("向 s1 添加单个字符: {}", s1);

    // 拼接字符串
    let s4 = s2 + &s3;
    println!("拼接字符串 s2 和 s3: {}", s4);

    // 迭代字符
    println!("迭代 s1 的字符:");
    for c in s1.chars() {
        println!("{}", c);
    }

    // 访问子字符串
    let s5 = "Hello, World!";
    let hello = &s5[0..5];
    println!("访问 s5 的子字符串: {}", hello);

    // === &str 的定义及常见操作 ===

    // 字符串字面量是 &str 类型
    let s6: &str = "Hello";
    println!("字符串字面量是 &str 类型: {}", s6);

    // 从 String 创建字符串切片
    let s7 = String::from("Hello, World!");
    let world: &str = &s7[7..12];
    println!("从 String 创建字符串切片: {}", world);

    // 字符串方法
    println!("s6 的字节长度: {}", s6.len());
    println!("s6 的字符数量: {}", s6.chars().count());

    // 模式匹配
    if let Some(index) = s6.find('e') {
        println!("在 s6 中找到字符 'e' 的位置: {}", index);
    }

    // === 综合操作 ===

    // 创建一个包含多个字符串的向量
    let mut vec = vec!["Hello", "World", "Rust", "Programming"];
    println!("初始向量: {:?}", vec);

    // 将向量中的字符串拼接成一个 String
    let joined = vec.join(", ");
    println!("将向量中的字符串拼接成一个 String: {}", joined);

    // 将拼接后的 String 转换为字符串切片
    let slice: &str = &joined;
    println!("将拼接后的 String 转换为字符串切片: {}", slice);

    // 在字符串切片中查找子字符串
    if let Some(index) = slice.find("Rust") {
        println!("在字符串切片中找到子字符串 'Rust' 的位置: {}", index);
    }

    // 修改向量中的字符串
    vec[1] = "Rustaceans";
    println!("修改向量中的字符串后: {:?}", vec);

    // 将修改后的向量中的字符串拼接成一个新的 String
    let new_joined = vec.join(", ");
    println!("将修改后的向量中的字符串拼接成一个新的 String: {}", new_joined);
}

运行结果

bash 复制代码
创建一个空的 String: ""
从字符串字面量创建 String: Hello
使用 to_string 方法创建 String: Hello
向 s1 添加字符串: , World!
向 s1 添加单个字符: , World!!
拼接字符串 s2 和 s3: HelloHello
迭代 s1 的字符:
,
 
W
o
r
l
d
!
!
访问 s5 的子字符串: Hello
字符串字面量是 &str 类型: Hello
从 String 创建字符串切片: World
s6 的字节长度: 5
s6 的字符数量: 5
在 s6 中找到字符 'e' 的位置: 1
初始向量: ["Hello", "World", "Rust", "Programming"]
将向量中的字符串拼接成一个 String: Hello, World, Rust, Programming
将拼接后的 String 转换为字符串切片: Hello, World, Rust, Programming
在字符串切片中找到子字符串 'Rust' 的位置: 14
修改向量中的字符串后: ["Hello", "Rustaceans", "Rust", "Programming"]
将修改后的向量中的字符串拼接成一个新的 String: Hello, Rustaceans, Rust, Programming

示例代码说明

  1. String 的定义及常见操作

    • 创建空的 String、从字符串字面量创建 String、使用 to_string 方法创建 String
    • 添加内容(push_strpush 方法)。
    • 拼接字符串(+ 操作符)。
    • 迭代字符(chars 方法)。
    • 访问子字符串(切片操作)。
  2. &str 的定义及常见操作

    • 字符串字面量是 &str 类型。
    • String 创建字符串切片。
    • 字符串方法(lenchars().count)。
    • 模式匹配(find 方法)。
  3. 综合操作

    • 创建包含多个字符串的向量。
    • 将向量中的字符串拼接成一个 String
    • 将拼接后的 String 转换为字符串切片。
    • 在字符串切片中查找子字符串。
    • 修改向量中的字符串并重新拼接。

这个示例代码涵盖了 Rust 中字符串类型和字符串切片的定义、常见操作以及综合应用,展示了它们在实际编程中的使用场景。

总结

Rust 的字符串类型主要包括 String&strString 是动态可变的 UTF-8 字符串,适用于需要动态修改的场景;&str 是不可变的字符串切片,适用于只读场景。合理使用这两种字符串类型可以提高代码的效率和可读性,同时充分利用 Rust 的内存安全特性。

相关推荐
iCxhust2 小时前
c# U盘映像生成工具
开发语言·单片机·c#
yangzhi_emo3 小时前
ES6笔记2
开发语言·前端·javascript
emplace_back4 小时前
C# 集合表达式和展开运算符 (..) 详解
开发语言·windows·c#
jz_ddk4 小时前
[学习] C语言数学库函数背后的故事:`double erf(double x)`
c语言·开发语言·学习
萧曵 丶4 小时前
Rust 所有权系统:深入浅出指南
开发语言·后端·rust
xiaolang_8616_wjl4 小时前
c++文字游戏_闯关打怪2.0(开源)
开发语言·c++·开源
收破烂的小熊猫~4 小时前
《Java修仙传:从凡胎到码帝》第四章:设计模式破万法
java·开发语言·设计模式
nananaij5 小时前
【Python进阶篇 面向对象程序设计(3) 继承】
开发语言·python·神经网络·pycharm
阿蒙Amon5 小时前
为什么 12 版仍封神?《C# 高级编程》:从.NET 5 到实战架构,进阶者绕不开的必修课
开发语言·c#