Lær at programmere i Rust · Lektion

Interior mutability: RefCell og Cell

Lær om `RefCell` og `Cell` til interior mutability, som gør det muligt at tilgå data mutabelt gennem en uforanderlig reference – på en sikker måde.

Lektion 2 af 311 trin

Interior mutability: RefCell og Cell er en gratis Lær at programmere i Rust-lektion på CoddyKit. Dette er lektion 2 af 3. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Lær at programmere i Rust, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Lær at programmere i Rust-kurset indeholder 3 lektioner i alt.

Hvad er indre mutabilitet?

I Rust forhindrer låne-reglerne dig normalt i at have en mutabel reference til data, hvis du allerede har en uforanderlig reference til dem. Det sikrer datasikkerheden.

Indre mutabilitet er et designmønster, der gør det muligt at ændre data, selv når du kun har en uforanderlig reference til dem. Det fungerer som en kontrolleret undtagelse fra Rusts normale regler og bruges i bestemte situationer.

`Cell<T>`: Til Copy-typer

Typen Cell<T> giver indre mutabilitet for typer, der implementerer traitet Copy, f.eks. heltal, booleske værdier og tegn. Den fungerer ved at erstatte værdien indeni.

  • get(): Returnerer en kopi af værdien i Cell.
  • set(value): Erstatter værdien i Cell med en ny værdi.

Det er enkelt og effektivt til små data, der kan kopieres.

Brug `Cell` til at opdatere værdier

Her er et grundlæggende eksempel på Cell. Bemærk, hvordan vi kan ændre værdien i Cell, selvom selve Cell er erklæret uforanderlig.

use std::cell::Cell;

fn main() {
  let my_num = Cell::new(10);
  println!("Initial value: {}", my_num.get());

  my_num.set(20);
  println!("Updated value: {}", my_num.get());

  let x = &my_num;
  x.set(30); // Still works via immutable reference!
  println!("Via immutable ref: {}", my_num.get());
}

`RefCell<T>`: Til typer, der ikke kan kopieres

Når du har brug for indre mutabilitet for typer, der ikke implementerer Copy (f.eks. String, Vec eller brugerdefinerede strukturer), bruger du RefCell<T>.

RefCell giver dig mulighed for at få mutable referencer til de indre data, men håndhæver Rusts låne-regler ved kørsel og ikke på kompileringstidspunktet.

`RefCell`-lån ved kørsel

RefCell indeholder metoder, der returnerer smarte pegere:

  • borrow(): Returnerer en Ref (en immutable smart peger). Du kan have flere immutable lån samtidig.
  • borrow_mut(): Returnerer en RefMut (en mutable smart peger). Du kan kun have ét mutable lån ad gangen.

Hvis du overtræder disse regler under kørsel, går dit program i panic!.

Brug af `RefCell` (immutable lån)

Her bruger vi borrow() til at få en immutable reference til den String, der ligger i RefCell. Vi kan udskrive dens indhold.

use std::cell::RefCell;

fn main() {
  let my_string_cell = RefCell::new(String::from("Hello"));

  let s1 = my_string_cell.borrow();
  println!("Value: {}", *s1); // Dereference Ref to get String

  let s2 = my_string_cell.borrow(); // Multiple immutable borrows are fine
  println!("Another value: {}", *s2);
}

Brug af `RefCell` (mutable lån)

Nu henter vi en mutable reference ved hjælp af borrow_mut(). Det giver os mulighed for at ændre String-værdien. Bemærk, at når s_mut er i gyldighedsområdet, er ingen andre lån (mutable eller immutable) tilladt.

use std::cell::RefCell;

fn main() {
  let my_string_cell = RefCell::new(String::from("World"));

  { // Scope for the mutable borrow
    let mut s_mut = my_string_cell.borrow_mut();
    s_mut.push_str(", Rust!");
  }
  // s_mut is out of scope here, so we can borrow again

  let s_final = my_string_cell.borrow();
  println!("Final value: {}", *s_final);
}

`RefCell`-panik ved kørsel

Hvis du forsøger at få et mutable lån, mens et andet mutable lån (eller et hvilket som helst immutable lån) er aktivt, får RefCell dit program til at gå i panic! under kørsel. Det forhindrer ødelæggelse af data.

Kør denne kode for at se det i praksis! Den går ned med en fejl om, at et lån allerede er i brug.

use std::cell::RefCell;

fn main() {
  let my_value = RefCell::new(vec![1, 2, 3]);

  let _first_mut_borrow = my_value.borrow_mut();
  println!("First mutable borrow is active.");

  // This line will cause a runtime panic!
  // Try commenting it out to see the program run successfully.
  let _second_mut_borrow = my_value.borrow_mut();

  println!("This line will not be reached.");
}

Opsummering af `Cell` og `RefCell`

Valget mellem Cell og RefCell afhænger af din datatype og af, hvordan du skal arbejde med den:

  • Cell<T>: Bruges til typer, der implementerer Copy. Den erstatter hele værdien og er som regel enklere og mere effektiv.
  • RefCell<T>: Bruges til typer, der ikke implementerer Copy. Den giver referencer til de indre data og håndhæver låne-reglerne under kørsel, så du kan udføre mere komplekse ændringer.

Hurtigt tjek: Cell eller RefCell?

Du har en struct, der skal gemme en mutable tæller (u32) og en mutable navneliste (Vec<String>), og begge skal opdateres via en immutable reference til struct. Hvilke typer til indre mutabilitet vil du bruge til hvert felt?

Opsummering: Indre mutabilitet

Du har lært om Rusts mønster for indre mutabilitet, som gør det muligt at ændre data via en immutable reference på en kontrolleret og sikker måde.

  • Cell<T>: Til Copy-typer; erstatter den indre værdi.
  • RefCell<T>: Til typer, der ikke implementerer Copy; giver mutable og immutable referencer, som kontrolleres under kørsel.
  • Hvis du overtræder RefCells regler, opstår der en panik under kørsel, hvilket sikrer sikkerheden.

Disse typer er afgørende for mønstre som mock-objekter, cirkulære referencer eller situationer, hvor en delt immutable reference skal holde styr på intern tilstand.

Gratis at komme i gang

Lær Rust med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
39
Lektioner
144

Ofte stillede spørgsmål

Er lektionen “Interior mutability: RefCell og Cell” gratis?

Ja — alle 3 lektioner i læringssporet Lær at programmere i Rust, inklusive “Interior mutability: RefCell og Cell”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Lær at programmere i Rust-kurset indeholder 3 lektioner i alt.

Hvad lærer jeg i “Interior mutability: RefCell og Cell”?

Lær om `RefCell` og `Cell` til interior mutability, som gør det muligt at tilgå data mutabelt gennem en uforanderlig reference – på en sikker måde. Du øver dig i Lær at programmere i Rust med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Lær at programmere i Rust?

Der kræves ingen tidligere erfaring. Lær at programmere i Rust på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 3.

Hvor lang tid tager lektionen “Interior mutability: RefCell og Cell”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Lær at programmere i Rust-lektion?

Ja. Alle Lær at programmere i Rust-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Smart pointers: Box, Rc og Arc
  2. Interior mutability: RefCell og Cell
  3. Ubange concurrency med tråde
← Tilbage til Lær at programmere i Rust