Direct naar de hoofdinhoud
Module 3 · Les 1 van 25/14 in de cursus~15 min
Modulelessen (1/2)

De eigendomsregels

Eigendom is het meest unieke kenmerk van Rust. Het zorgt ervoor dat de taal geheugenveiligheid kan garanderen zonder dat je een Garbage Collector nodig hebt of dat je gedwongen wordt om de toewijzing van heapgeheugen handmatig ongedaan te maken (zoals in C of C++).

De drie eigendomsregels

Geheugenbeheer in Rust wordt beheerst door drie eenvoudige regels die strikt worden gecontroleerd door de compiler:

  1. Elke waarde in Rust heeft een variabele die de eigenaar wordt genoemd.
  2. Er kan slechts één eigenaar tegelijk zijn.
  3. Als de eigenaar buiten bereik valt, wordt de waarde automatisch verwijderd.

Stapel versus hoop

Om eigendom te begrijpen, is het belangrijk om te weten waar gegevens zich bevinden:

  • Stack: slaat gegevens met een vaste grootte op die bekend zijn tijdens het compileren (bijvoorbeeld gehele getallen, booleans). De toegang is extreem snel.
  • Heap: slaat gegevens van dynamische grootte op die onbekend zijn tijdens het compileren (bijvoorbeeld String). Toewijzing is langzamer en vereist een aanwijzer die op de stapel is opgeslagen.

Het concept van ‘bewegen’

Wanneer we een door de heap toegewezen variabele aan een andere toewijzen, verplaatst (of draagt) Rust het eigendom van de waarde over, waardoor de eerste variabele ongeldig wordt:

Rust
let s1 = String::from("ciao");
let s2 = s1; // Ownership of the text moves to s2. s1 is NO longer usable!

// println!("{}", s1); // COMPILATION ERROR! s1 is "borrow of moved value"
println!("{}", s2); // Valid!

Dit gedrag vermijdt de "dubbele vrije fout" (tweemaal proberen hetzelfde geheugen vrij te maken wanneer het buiten bereik valt), omdat alleen s2 het geheugen vrijmaakt.

Het concept van "kloon" (diepe kopie)

Als we expliciet de volledige inhoud van een String moeten kopiëren (zowel de stapelaanwijzers als de daadwerkelijke tekstgegevens in de heap), kunnen we de methode .clone() gebruiken. Hierdoor worden de gegevens op de heap volledig gedupliceerd, waarbij zowel de originele als de nieuwe variabele geldig blijven, ten koste van prestatieoverhead voor de nieuwe geheugentoewijzing:

Rust
let s1 = String::from("ciao");
let s2 = s1.clone(); // Deep copy. Both variables remain valid!
println!("s1: {}, s2: {}", s1, s2);

Het concept van "kopiëren"

Voor eenvoudige typen die volledig op de Stack zijn opgeslagen (zoals gehele getallen i32, booleans bool, tekens char), voert de toewijzing een daadwerkelijke automatische ondiepe kopie uit, wat betekent dat beide variabelen geldig blijven:

Rust
let x = 5;
let y = x; // Copies the value 5 onto the stack. Both variables are usable!
println!("x: {}, y: {}", x, y); // Valid!

Probeer het zelf

Oefening#rust.m3.l1.e1
Pogingen: 0Laden…

Declareer een String s1 met de tekst 'hallo'. Wijs s1 toe aan s2 (om het eigendom te verplaatsen). Tenslotte drukt u s2 af met println!.

Editor laden…
Toon hint

Gebruik `let s2 = s1;` om het eigendom over te dragen aan `s2` en druk het af met `println!('{}', s2);`.

Oplossing beschikbaar na 3 pogingen

Oefening#rust.m3.l1.e2
Pogingen: 0Laden…

Declareer een geheel getal variabele x met een waarde van 5. Wijs x toe aan y (een kopie uitvoeren). Tenslotte drukt u zowel x als y af in dezelfde println! stelling.

Editor laden…
Toon hint

Voer `let y = x;` uit en druk vervolgens beide waarden af, bijvoorbeeld `println!('{} {}', x, y);`.

Oplossing beschikbaar na 3 pogingen

Oefening#rust.m3.l1.e3
Pogingen: 0Laden…

Declare a String s1 with the value "Rust". Create a deep copy of s1 in a new variable s2 using the clone method. Finally, print both s1 and s2 separated by a space using the println! macro.

Editor laden…
Toon hint

Use `let s2 = s1.clone();` to deep copy the value of `s1` into `s2`, then print them with `println!("{} {}", s1, s2);`.

Oplossing beschikbaar na 3 pogingen