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

【Rust】 6. 字符串学习笔记

一、Rust 字符串概述

Rust 字符串是 UTF-8 编码的文本序列,提供两种主要类型:

  1. &str - 字符串切片(通常作为引用出现)
  2. String - 动态可变的、拥有所有权的字符串

二、字符串字面量 (&str)

编译时已知大小,静态分配在只读内存中

let greeting: &str = "Hello, world!";
println!("字符串字面量: {}", greeting);

三、String 类型

动态分配在堆上,可增长和修改的所有权字符串

let mut s = String::from("Hello");
s.push_str(", world!");
println!("String 类型: {}", s);

四、创建 String 的多种方式

  1. 创建空字符串
let empty = String::new();
println!("空字符串: '{}'", empty);
  1. 从字面量创建
let from_literal = String::from("初始内容");
println!("从字面量创建: {}", from_literal);
  1. 使用 to_string() 方法
let to_string = "另一个字符串".to_string();
println!("to_string(): {}", to_string);
  1. 使用 format! 宏
let formatted = format!("格式化 {} {}", "字符串", 123);
println!("format! 宏: {}", formatted);

五、修改 String

let mut mutable_string = String::from("Hello");
// 添加单个字符
mutable_string.push('!');
println!("添加字符后: {}", mutable_string);// 添加字符串切片
mutable_string.push_str(" World");
println!("添加字符串后: {}", mutable_string);// 在指定位置插入
mutable_string.insert_str(6, "Rust ");
println!("插入后: {}", mutable_string);

六、字符串访问和迭代

let text = String::from("Hello");// 获取第一个字符(Option<char> 类型)
if let Some(first_char) = text.chars().nth(0) {println!("第一个字符: {}", first_char);
}// 迭代所有字符
print!("字符迭代: ");
for c in text.chars() {print!("{} ", c);
}
println!();// 字符串切片(注意:基于字节索引,非ASCII字符需要小心)
let slice = &text[0..1]; // "H"
println!("切片: {}", slice);

七、Unicode 和非 ASCII 字符处理

let unicode_text = "Здравствуйте"; // 俄语"你好"
println!("Unicode 文本: {}", unicode_text);// 字符数统计(不是字节数)
let char_count = unicode_text.chars().count();
let byte_count = unicode_text.len();
println!("字符数: {}, 字节数: {}", char_count, byte_count);// 遍历 Unicode 字符
print!("Unicode 字符: ");
for c in unicode_text.chars() {print!("{} ", c);
}
println!();

八、字符串转换和操作

let original = String::from("hello");// 转换为大写(返回新字符串)
let upper = original.to_uppercase();
println!("大写: {}", upper);// 转换为小写
let lower = upper.to_lowercase();
println!("小写: {}", lower);// 字符串替换
let replaced = original.replace("he", "she");
println!("替换后: {}", replaced);// 字符串分割
let sentence = "Rust is awesome!";
let words: Vec<&str> = sentence.split_whitespace().collect();
println!("分割单词: {:?}", words);

九、&str 和 String 的关系与转换

// &str → String(需要分配内存)
let slice: &str = "切片";
let owned: String = slice.to_string();
println!("&str 转 String: {}", owned);// String → &str(零成本转换)
fn process_text(text: &str) {println!("处理文本: {}", text);
}let string_data = String::from("一些数据");
process_text(&string_data); // 自动解引用转换

十、原始字符串和转义

// 普通转义
let escaped = "包含\"引号\"和\\反斜杠";
println!("转义字符串: {}", escaped);// 原始字符串(避免转义)
let raw = r#"原始字符串: "内容" 和 \反斜杠"#;
println!("原始字符串: {}", raw);// 多级原始字符串(处理包含 # 的文本)
let complex_raw = r###"包含 # 号的 "原始" 字符串"###;
println!("复杂原始字符串: {}", complex_raw);

十一、字符串索引的注意事项

// Rust 不允许直接索引字符串(因UTF-8变长编码)
let sample = "Rust编程";// 错误:不能直接索引
// let first_char = sample[0]; // 正确方式:使用字符迭代
if let Some(first) = sample.chars().nth(0) {println!("第一个字符: {}", first);
}// 获取字符向量(注意性能开销)
let chars: Vec<char> = sample.chars().collect();
println!("字符向量: {:?}", chars);

十二、字符串连接

// 使用 + 运算符(会获取所有权)
let s1 = String::from("Hello");
let s2 = String::from(" World");
let combined = s1 + &s2; // s1 被移动,不能再使用
println!("连接后: {}", combined);// 使用 format! 宏(推荐,不会获取所有权)
let s3 = String::from("Hello");
let s4 = String::from(" World");
let formatted_combine = format!("{}{}", s3, s4);
println!("format! 连接: {}", formatted_combine);
// s3 和 s4 仍然可用

十三、实用字符串方法

let example = String::from("   Rust Programming   ");// 去除首尾空白
let trimmed = example.trim();
println!("去除空白: '{}'", trimmed);// 检查是否包含子串
let contains = example.contains("Rust");
println!("包含 'Rust': {}", contains);// 查找子串位置
if let Some(pos) = example.find("Programming") {println!("'Programming' 位置: {}", pos);
}// 字符串长度(字节数)
println!("字节长度: {}", example.len());// 判断是否为空
println!("是否为空: {}", example.is_empty());

十四、总结:

  • &str: 静态、不可变、零成本抽象的字符串视图
  • String: 动态、可变、拥有所有权的字符串
  • UTF-8 编码确保完整的 Unicode 支持
  • 设计注重内存安全和性能
  • 丰富的API支持各种字符串操作

性能提示:频繁的字符串修改建议使用 String,只读操作使用 &str

http://www.dtcms.com/a/357259.html

相关文章:

  • Day12-python文件操作(二)
  • java开发连接websocket接口
  • STM32CubeMX(十八)USB-MSC:外部flash模拟U盘
  • Day17_【机器学习—特征预处理(归一化和标准化)】
  • 期权杂记(二)
  • Hadoop(六)
  • 迁移学习实战:医疗影像识别快速突破方案
  • 【实时Linux实战系列】实时数据可视化技术实现
  • Python OpenCV图像处理与深度学习:Python OpenCV开发环境搭建与入门
  • 嵌入式Linux驱动开发:设备树与平台设备驱动
  • 2023年12月GESP5级C++真题解析,包括选择判断和编程
  • 嵌入式-定时器的输入捕获,超声波获距实验-Day23
  • 如何使用 Vector 连接 Easysearch
  • 【实时Linux实战系列】实时环境监控系统的架构与实现
  • PPT处理控件Aspose.Slides教程:使用 C# 编程将 PPTX 转换为 XML
  • 【实时Linux实战系列】基于实时Linux的虚拟现实应用开发
  • 趣味学Rust基础篇(所有权)
  • 【DeepSeek】公司内网部署离线deepseek+docker+ragflow本地模型实战
  • 《跳出“技术堆砌”陷阱,构建可演进的软件系统》
  • 【PyTorch】神经风格迁移项目
  • 每周资讯 | 《恋与深空》获科隆游戏展2025“最佳移动游戏奖”;8月173个版号下发
  • 【小白笔记】访问GitHub 账户的权限英文单词解释
  • nvm使用和node使用
  • 【前端教程】用 JavaScript 实现4个常用时间与颜色交互功能
  • centos8部署miniconda、nodejs
  • webpack升级
  • 飞牛Nas每天定时加密数据备份到网盘,基于restic的Backrest笔记分享
  • linux和RTOS架构区别
  • 通过 KafkaMQ 接入Skywalking 数据最佳实践
  • JAVA:Spring Boot 集成 Easy Rules 实现规则引擎