Zoeken…
Invoering
String
(een heap-toegewezen stringtype) en &str
(een geleende string, die geen extra geheugen gebruikt). Het is belangrijk om het verschil te kennen en te weten wanneer je ze moet gebruiken om te begrijpen hoe Rust werkt.
Basic String manipulatie
fn main() {
// Statically allocated string slice
let hello = "Hello world";
// This is equivalent to the previous one
let hello_again: &'static str = "Hello world";
// An empty String
let mut string = String::new();
// An empty String with a pre-allocated initial buffer
let mut capacity = String::with_capacity(10);
// Add a string slice to a String
string.push_str("foo");
// From a string slice to a String
// Note: Prior to Rust 1.9.0 the to_owned method was faster
// than to_string. Nowadays, they are equivalent.
let bar = "foo".to_owned();
let qux = "foo".to_string();
// The String::from method is another way to convert a
// string slice to an owned String.
let baz = String::from("foo");
// Coerce a String into &str with &
let baz: &str = &bar;
}
Opmerking: Zowel de String::new
als de String::with_capacity
methoden zullen lege strings maken. De laatste wijst echter een initiële buffer toe, waardoor deze aanvankelijk langzamer wordt, maar de volgende toewijzingen helpen verminderen. Als de uiteindelijke grootte van de tekenreeks bekend is, String::with_capacity
de voorkeur.
String snijden
fn main() {
let english = "Hello, World!";
println!("{}", &english[0..5]); // Prints "Hello"
println!("{}", &english[7..]); // Prints "World!"
}
Merk op dat we de &
operator hier moeten gebruiken. Het heeft een referentie nodig en geeft de compiler informatie over de grootte van het schijftype, dat hij nodig heeft om het af te drukken. Zonder de referentie, de twee println!
oproepen zouden een compilatie-fout zijn.
Waarschuwing: Slicing werkt op byte-offset , niet op karakter-offset en raakt in paniek als de grenzen niet op een karaktergrens liggen:
fn main() {
let icelandic = "Halló, heimur!"; // note that “ó” is two-byte long in UTF-8
println!("{}", &icelandic[0..6]); // Prints "Halló", “ó” lies on two bytes 5 and 6
println!("{}", &icelandic[8..]); // Prints "heimur!", the “h” is the 8th byte, but the 7th char
println!("{}", &icelandic[0..5]); // Panics!
}
Dit is ook de reden waarom strings geen eenvoudige indexering ondersteunen (bijv. icelandic[5]
).
Split een string
let strings = "bananas,apples,pear".split(",");
split
geeft een iterator terug.
for s in strings {
println!("{}", s)
}
En kan worden "verzameld" in een Vec
met de Iterator::collect
methode.
let strings: Vec<&str> = "bananas,apples,pear".split(",").collect(); // ["bananas", "apples", "pear"]
Van geleend naar eigendom
// all variables `s` have the type `String`
let s = "hi".to_string(); // Generic way to convert into `String`. This works
// for all types that implement `Display`.
let s = "hi".to_owned(); // Clearly states the intend of obtaining an owned object
let s: String = "hi".into(); // Generic conversion, type annotation required
let s: String = From::from("hi"); // in both cases!
let s = String::from("hi"); // Calling the `from` impl explicitly -- the `From`
// trait has to be in scope!
let s = format!("hi"); // Using the formatting functionality (this has some
// overhead)
Afgezien van de format!()
, Zijn alle bovenstaande methoden even snel.
Lange letterreeksen doorbreken
Breek reguliere tekenreeksliteralen met het \
-teken
let a = "foobar";
let b = "foo\
bar";
// `a` and `b` are equal.
assert_eq!(a,b);
Breek raw-string literals om afzonderlijke strings te scheiden en voeg ze bij de concat!
macro
let c = r"foo\bar";
let d = concat!(r"foo\", r"bar");
// `c` and `d` are equal.
assert_eq!(c, d);