Achtergrond:
In vergelijking met native talen (C/C++) biedt Rust veilige omgang met strings door strikte scheiding van referentietypen (&str) en eigendomstypen (String). Dit voorkomt de meeste fouten die verband houden met onjuiste geheugentoegang, bufferoverlopen en double-free.
Probleem:
In tegenstelling tot volwassen GC-talen, waar elke string leeft in beheerd geheugen, moet je in Rust duidelijk begrijpen wie de string bezit, hoe lang deze leeft en hoe je geen dangling reference krijgt na wijzigingen. Het werken met UTF-8-strings vereist voorzichtigheid bij indexeren en wijzigen.
Oplossing:
In Rust is String een veranderlijke, heap-gealloceerde string die zijn inhoud bezit. &str is een onveranderlijke referentie naar een byte-reeks met de garantie van UTF-8. Indien nodig kan je veilig converteren (&str -> String en omgekeerd) met behulp van standaardmethoden.
Voorbeeldcode:
fn main() { let owned: String = String::from("Rust"); let borrowed: &str = &owned; let primitive: &str = "Hello"; // literaal is altijd &str // Converteren &str -> String let s: String = primitive.to_string(); // Converteren String -> &str let st: &str = &s; println!("{} {} {} {}", owned, borrowed, primitive, st); }
Belangrijke kenmerken:
&'static str, en niet StringWaarom kun je een string niet indexeren als s[1] of s[i]?
Rust-strings zijn in UTF-8, dus directe indexering is niet beschikbaar: s[i] geeft niet het i-de karakter terug en kan soms tot panic leiden bij toegang tot een onjuiste bytegrens. Gebruik in plaats daarvan de methoden .chars().nth(i) of .get(start..end).
Kan je &str veilig wijzigen?
Nee - &str is altijd een immutable slice. Voor wijzigingen gebruik je to_owned/to_string, of gebruik String/Vec<u8>.
Wat is het fundamentele verschil tussen String::from("abc") en "abc".to_string()?
Deze opties zijn equivalent qua resultaat, beide creëren een String door gegevens uit &str te kopiëren. Het enige verschil is de stijl: bijvoorbeeld, to_string is geïmplementeerd via de trait ToString, terwijl String::from duidelijker de intentie „eigendom creëren” uitdrukt.
De functie accepteerde String en deed onnodige kopieën van de string intern (clone), en schreef vervolgens een slice naar een andere functie, terwijl de levensduur van de bron niet werd verlengd. Resultaat: dangling reference & crash.
Voordelen:
Nadelen:
De functie accepteert &str, en indien wijzigingen nodig zijn, roept deze .to_string() aan; de logica blijft "zero copy". Levensduur is onder controle, geen enkele overbodige allocatie.
Voordelen:
Nadelen: