引言
在 Rust 中,字符串处理是一个非常重要的话题。作为初学者,最常见的困惑就是在 String
和 &str
之间如何选择。本文将为你揭开这个谜题,让你轻松掌握字符串类型的选择技巧。
四个层次的使用原则
第一层:简单粗暴,全用 String
对于初学者来说,最简单的方式就是统一使用 String
。虽然可能需要更多的 .to_string()
或 .clone()
,但能确保代码正常运行。
struct Person {
name: String, // 使用 String 类型
}
fn first_word(words: String) -> String {
// 返回第一个单词
words
.split_whitespace()
.next()
.expect("words should not be empty")
.to_string()
}
fn main() {
let sentence = "Hello,world!";
// 需要转换为 String
println!("{}", first_word(sentence.to_string()));
}
第二层:函数参数优先使用 &str
进阶一点的方案是:结构体中使用 String
,函数参数使用 &str
,返回值使用 String
。这样可以减少不必要的复制操作。
struct Person {
name: String,
}
fn first_word(words: &str) -> String {
// 参数使用 &str
words
.split_whitespace()
.next()
.expect("words should not be empty")
.to_string()
}
fn main() {
let sentence = "Hello,world!";
// 不需要转换,直接传递字符串字面量
println!("{}", first_word(sentence));
}
第三层:返回值也考虑使用 &str
更进一步的优化是:如果函数返回的是参数的子串,而且没有修改,可以返回 &str
。
fn first_word(words: &str) -> &str {
// 直接返回子串引用
words
.split_whitespace()
.next()
.expect("words should not be empty")
}
fn first_word_uppercase(words: &str) -> String {
// 因为要修改内容,所以返回 String
words
.split_whitespace()
.next()
.expect("words should not be empty")
.to_uppercase()
}
第四层:结构体中的 &str
对于结构体中是否使用 &str
,建议是:如果你在问这个问题,那就用 String
。当你真的需要在结构体中使用 &str
时,你自然会知道。
总结
初学者可以统一使用 String
随着对 Rust 的理解加深,逐步在函数参数中使用 &str
进一步优化时,可以在合适的场景返回 &str
结构体中优先使用 String
,除非有特殊需求
记住这些原则,能帮助你写出更好的 Rust 代码。不必过分纠结选择问题,随着经验增长,你会自然而然地掌握最佳实践。
参考文章
When should I use String vs &str?: https://steveklabnik.com/writing/when-should-i-use-string-vs-str/
书籍推荐
各位 Rust 爱好者,今天为大家介绍一本《Programming Rust: Fast, Safe Systems Development》(第二版) 是由 Jim Blandy、Jason Orendorff 和 Leonora Tindall 合著的 Rust 编程指南。本书深入探讨了 Rust 语言在系统编程中的应用,着重介绍如何利用 Rust 的独特特性来平衡性能和安全性。书中涵盖了 Rust 的基础数据类型、所有权和借用概念、特征和泛型、并发编程、闭包、迭代器以及异步编程等核心内容。这本更新版基于 Rust 2021 版本,为系统程序员提供了全面而实用的 Rust 编程指导。