Rust 用两种方式实现字符数组:str 和 String。
str 也称为“字符串切片”,通常配合引用使用,写作 &str。
想知道原因,可以先看看下面这行代码为什么无法编译:
const MY_CONST: str = *"Hello, World!";
// the size for values of type `str` cannot be known at compilation time
// the trait `Sized` is not implemented for `str`
尽管字面量 "Hello, World!" 的长度在编译时就能确定,但作为 str,它是一个大小未知的序列。
但作为指向字面量的_引用_(&str)时,它带有一个“胖指针”,其中保存了该字面量在内存中的地址和长度。
胖指针的大小是已知的,因此下面这行可以编译:
const MY_CONST: &str = "Hello, World!";
指向字符串切片的可变绑定可以替换其值,但不能就地修改。
示例:
let mut my_str = "Hello, World!";
my_str = "Hi!";
let mut my_string = String::from("Hello");
my_string.push_str(", World!"); // there is no equivalent function to modify &str
在为函数定义形参时,使用 &str 比 &String 限制更少,因为下面这段代码无法编译:
pub fn main() {
let my_str: &str = "Hello, World!";
say_hi(my_str);
}
fn say_hi(phrase: &String) {
println!("{phrase:?}");
}
// mismatched types
// expected reference `&String`
// found reference `&str`
&str不会强制转换成 &String。但下面这段代码可以编译:
pub fn main() {
let my_string = String::from("Hello, World!");
say_hi(&my_string)
}
fn say_hi(phrase: &str) {
println!("{phrase:?}");
}
&String会强制转换成 &str。所以把形参类型写成 &str 往往更有用。