Rust implementa un array de caracteres de dos maneras: str y String.
str, también conocido como «string slice», se suele usar con una referencia como &str.
Para saber por qué, puede ayudar entender por qué la siguiente línea de código no compilará
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`
Aunque la longitud del literal "Hello, World!" se puede conocer en tiempo de compilación, como str es una secuencia de tamaño desconocido.
Pero como referencia a un literal (&str), tiene un «fat pointer» que contiene la dirección y la longitud del literal en memoria.
Los «fat pointers» son de tamaño conocido, así que esta línea compilará
const MY_CONST: &str = "Hello, World!";
Un enlace mutable a un string slice puede ver su valor reemplazado, pero no modificado in situ.
Ejemplo
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
Es menos restrictivo usar &str en lugar de &String al definir un parámetro para una función, ya que esto no compilará
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`
Un &str no será coaccionado a un &String. Pero esto sí compilará
pub fn main() {
let my_string = String::from("Hello, World!");
say_hi(&my_string)
}
fn say_hi(phrase: &str) {
println!("{phrase:?}");
}
Un &String será coaccionado a un &str. Así que usar un tipo de parámetro &str a menudo será más útil.