跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Rust字符串切片
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= Rust字符串切片 = '''Rust字符串切片'''(String Slice)是Rust所有权系统中处理字符串数据的重要概念,它提供了一种安全、高效的方式来引用字符串的一部分,而无需复制数据。字符串切片是Rust内存安全保证的核心机制之一。 == 基本概念 == 字符串切片是一个指向字符串某部分的不可变引用,类型表示为<code>&str</code>。它由两部分组成: * 指向数据的指针 * 长度信息(以字节计) 切片允许你引用集合中连续的元素序列,而不是整个集合。对于字符串而言,切片总是有效的UTF-8序列。 === 语法表示 === 字符串切片的语法形式为: <syntaxhighlight lang="rust"> let slice = &string[start..end]; // 包含start,不包含end </syntaxhighlight> == 创建字符串切片 == === 从String创建 === <syntaxhighlight lang="rust"> fn main() { let s = String::from("hello world"); let hello = &s[0..5]; // 或 &s[..5] let world = &s[6..11]; // 或 &s[6..] let whole = &s[..]; // 整个字符串切片 println!("{}", hello); // 输出: hello println!("{}", world); // 输出: world println!("{}", whole); // 输出: hello world } </syntaxhighlight> === 字符串字面量就是切片 === 字符串字面量实际上就是切片: <syntaxhighlight lang="rust"> let s: &str = "Hello, world!"; </syntaxhighlight> == 内存表示 == <mermaid> graph LR A[String] -->|堆内存| B("hello world") C[&str hello] -->|引用| D("hello") E[&str world] -->|引用| F("world") </mermaid> == 重要特性 == === UTF-8安全 === Rust会确保字符串切片始终是有效的UTF-8序列。尝试创建无效的UTF-8切片会导致panic: <syntaxhighlight lang="rust"> fn main() { let s = String::from("Здравствуйте"); let slice = &s[0..1]; // panic! 因为'З'占2字节 } </syntaxhighlight> === 不可变性 === 字符串切片总是不可变的引用,这保证了内存安全: <syntaxhighlight lang="rust"> fn main() { let mut s = String::from("hello"); let slice = &s[..]; s.push_str(", world!"); // 错误!不能同时存在可变和不可变引用 println!("{}", slice); } </syntaxhighlight> == 实际应用案例 == === 函数参数 === 使用<code>&str</code>作为函数参数比<code>String</code>更灵活: <syntaxhighlight lang="rust"> fn print_first_word(s: &str) -> &str { let bytes = s.as_bytes(); for (i, &item) in bytes.iter().enumerate() { if item == b' ' { return &s[0..i]; } } &s[..] } fn main() { let s = String::from("hello world"); let word = print_first_word(&s); println!("第一个单词: {}", word); // 输出: hello let literal = "foo bar"; let word = print_first_word(literal); println!("第一个单词: {}", word); // 输出: foo } </syntaxhighlight> === 高效字符串处理 === 避免不必要的复制: <syntaxhighlight lang="rust"> fn get_file_extension(filename: &str) -> Option<&str> { filename.split('.').last() } fn main() { let path = "archive.tar.gz"; match get_file_extension(path) { Some(ext) => println!("文件扩展名: {}", ext), None => println!("无扩展名"), } } </syntaxhighlight> == 高级主题 == === 生命周期关联 === 字符串切片与生命周期密切相关: <syntaxhighlight lang="rust"> fn longest<'a>(s1: &'a str, s2: &'a str) -> &'a str { if s1.len() > s2.len() { s1 } else { s2 } } </syntaxhighlight> === 与String的区别 === {| class="wikitable" |- ! 特性 !! String !! &str |- | 所有权 || 拥有 || 借用 |- | 大小 || 可变 || 固定 |- | 存储位置 || 堆 || 可以是堆或静态内存 |- | 可变性 || 可变 || 不可变 |} == 常见错误及解决 == === 切片越界 === 尝试超出字符串范围的切片会导致panic: <syntaxhighlight lang="rust"> let s = "hello"; let slice = &s[0..10]; // panic! </syntaxhighlight> 解决方案:使用<code>s.len()</code>检查长度或捕获错误。 === 无效UTF-8 === 如前所述,必须确保切片边界在UTF-8字符边界上。可以使用<code>char_indices()</code>方法安全处理: <syntaxhighlight lang="rust"> fn safe_slice(s: &str, start: usize, end: usize) -> Option<&str> { let mut char_pos = 0; let mut byte_start = None; let mut byte_end = None; for (i, (byte_pos, _)) in s.char_indices().enumerate() { if i == start { byte_start = Some(byte_pos); } if i == end { byte_end = Some(byte_pos); break; } } match (byte_start, byte_end) { (Some(s), Some(e)) => Some(&s[s..e]), _ => None, } } </syntaxhighlight> == 性能考虑 == 字符串切片的优势在于: * 零成本抽象 - 不涉及堆分配 * 避免了数据复制 * 编译时检查保证安全性 数学上,切片的访问时间复杂度是<math>O(1)</math>,因为它只是指针操作。 == 总结 == Rust字符串切片是: * 对字符串部分内容的引用 * 类型为<code>&str</code> * 保证内存安全和UTF-8有效性 * 高效且灵活,适合作为函数参数 * 与Rust所有权系统深度集成 掌握字符串切片是理解Rust内存模型的关键步骤,也是编写高效、安全Rust代码的基础。 [[Category:编程语言]] [[Category:Rust]] [[Category:Rust所有权系统]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)