Rust реалізує масив символів двома способами: str і String.
str, який також називають зрізом рядка тексту (англ. string), зазвичай використовують із посиланням як &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 часто буде корисніше.