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

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

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

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

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

关键词:字符串


一、String 类型

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

特点

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

创建 String

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

常见操作

  • 添加内容

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

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

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

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

二、字符串切片 &str

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

特点

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

创建 &str

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

常见操作

1. 字符串方法

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

2. 模式匹配

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 的常见用法:

fn main() {// 创建 Stringlet 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)的定义及常见操作:

fn main() {// === String 的定义及常见操作 ===// 创建一个空的 Stringlet mut s1 = String::new();println!("创建一个空的 String: {:?}", s1);// 从字符串字面量创建 Stringlet s2 = String::from("Hello");println!("从字符串字面量创建 String: {}", s2);// 使用 to_string 方法从字符串字面量创建 Stringlet 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);// 将向量中的字符串拼接成一个 Stringlet 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);// 将修改后的向量中的字符串拼接成一个新的 Stringlet new_joined = vec.join(", ");println!("将修改后的向量中的字符串拼接成一个新的 String: {}", new_joined);
}

运行结果

创建一个空的 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 的内存安全特性。

http://www.xdnf.cn/news/5776.html

相关文章:

  • Linux常用命令(持续完善)
  • DAY05:深入解析生命周期与钩子函数
  • 编写一个处理txt的loader插件,适用于wbepack
  • MCU开启浮点计算FPU
  • 【Pandas】pandas DataFrame cov
  • tabs切换#
  • JVM之垃圾回收器
  • Java SpringMVC 和 MyBatis 整合关键配置详解
  • 步进电机、伺服电机与直流无刷电机的高速运动性能对比及技术瓶颈分析
  • Github 2025-05-12 开源项目周报 Top15
  • Feed流推送之订阅推送
  • ChromeDriver 技术生态与应用场景深度解析
  • VUE中通过DOM导出PDF
  • UI-TARS: 基于视觉语言模型的多模式代理
  • FLASH闪存(擦除、编译)
  • Golang 空结构体特性与用法
  • 位运算的巧思:以一道简单题看高效算法的设计精髓
  • 可视化图解算法37:序列化二叉树-II
  • MCP与GitHub的集成:开发者的“自动化流水线”革命
  • ThreadLocal 详解
  • 2025年阿里云ACP大数据分析师认证模拟试题(附答案解析)
  • JVM对象分配与程序崩溃排查
  • Git的基本操作
  • Jupyter-AI Pandas-AI本地使用功能优化
  • 识别人脸人名,只是窗口的中文乱码待解决
  • 数据库实验报告 SQL SERVER 2008的基本操作 1
  • 调出事件查看器界面的4种方法
  • 从规划到完善,原型标注图全流程设计
  • 国产化芯片ZCC3790--同步升降压控制器的全新选择, 替代LT3790
  • 接口和抽象类的区别