ProgrammatieRust Backend ontwikkelaar

Leg uit hoe borrowing en aliasing werken in Rust. Wat zijn de beperkingen voor gelijktijdig gebruik van mutabele en niet-mutabele referenties, hoe wordt dit gecontroleerd door de compiler en wat kan er misgaan?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

Borrowing (lenen) in Rust is een mechanisme voor het tijdelijk "lenen" van een variabele via referenties. Rust maakt onderscheid tussen niet-mutabele leningen (&T) en mutabele (&mut T). Er kunnen oneindig veel niet-mutabele referenties bestaan, maar slechts één mutabele. Gelijktijdig bestaan van mutabele en niet-mutabele referenties naar hetzelfde object is niet toegestaan.

Deze regel garandeert de afwezigheid van data race op het compilatieniveau en maakt Rust veilig voor gelijktijdig programmeren.

Voorbeeld:

let mut value = 5; let r1 = &value; let r2 = &value; // let r3 = &mut value; // FOUT: je kunt geen &mut creëren terwijl er een & is println!("{} {}", r1, r2); // r3 is verboden tot het einde van de scope van r1/r2

Vragend met een val

Vraag: Is het mogelijk om in één scope een &mut referentie en zoveel & referenties naar hetzelfde object te creëren?

Typisch onjuist antwoord: Ja, maar alleen als ze niet overlappen in levensduur.

Juiste antwoord: Een mutabele en niet-mutabele referentie naar hetzelfde object kan niet gelijktijdig bestaan (zelfs niet als hun toegang in de statische code niet overlapt), zolang de ene leeft, zijn de anderen verboden. De veiligheid wordt gecontroleerd door de borrow checker.

Voorbeeld:

let mut x = 10; let y = &x; let z = &mut x; // Fout, y is nog steeds in scope println!("{}", y); // y is later nodig

Voorbeelden van echte fouten door gebrek aan kennis over de nuances van het onderwerp


Verhaal

In een groot project met parallelle gegevensverwerking besloot een ontwikkelaar niet-mutabele referenties naar een vector te gebruiken en probeerde daarna een mutabele referentie te krijgen voor sorteren. De code werkte in de test, maar stopte met compileren na refactoring, omdat de levensduur van de niet-mutabele referenties was verlengd.


Verhaal

In een interne service werd een structuur gewijzigd via &mut, terwijl er referenties naar velden werden behouden voor verdere verzending naar een andere thread. Dit leidde tot een data race en crash door het niet naleven van de borrow regels - Rust beschermt hiertegen alleen op het compilatieniveau, maar de fouten waren in unsafe-blokken waar garanties zijn opgeheven.


Verhaal

Onjuiste documentatie van de API: de bibliotheek accepteerde gelijktijdig & en &mut voor verschillende velden van de structuur, maar door aliasing werd de invariantie geschonden en ontstonden er lastig te traceren bugs met de diensten die deze bibliotheek integreerden.