Rust kennt zwei Möglichkeiten, ein Array von Zeichen umzusetzen: str und String.
str, auch als „string slice“ bekannt, wird normalerweise mit einer Referenz als &str verwendet.
Um das zu verstehen, ist es hilfreich, zu wissen, warum die folgende Codezeile nicht kompiliert
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`
Auch wenn die Länge des Literals „Hello, World!“ zur Kompilierzeit bekannt ist, handelt es sich bei einem str um eine Sequenz unbekannter Größe.
Als Referenz auf ein Literal (&str) hat es jedoch einen „Fat Pointer“, der die Adresse und die Länge des Literals im Speicher enthält.
Fat Pointer haben eine bekannte Größe, deshalb kompiliert diese Zeile
const MY_CONST: &str = "Hello, World!";
Bei einer veränderlichen Bindung an einen string slice lässt sich der Wert ersetzen, aber nicht an Ort und Stelle verändern.
Beispiel
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 ist weniger einschränkend, &str statt &String als Parameter einer Funktion zu verwenden, denn Folgendes kompiliert nicht
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`
Ein &str wird nicht in ein &String umgewandelt. Aber Folgendes kompiliert
pub fn main() {
let my_string = String::from("Hello, World!");
say_hi(&my_string)
}
fn say_hi(phrase: &str) {
println!("{phrase:?}");
}
Ein &String wird in ein &str umgewandelt. Daher ist es oft nützlicher, &str als Parametertyp zu verwenden.