Lær Rust-programmering · leksjon

Intern muterbarhet: RefCell, Cell

Lær om `RefCell` og `Cell` for intern muterbarhet, slik at data trygt kan endres gjennom en uforanderlig referanse.

Leksjon 2 av 311 trinn

Intern muterbarhet: RefCell, Cell er en gratis leksjon i Lær Rust-programmering på CoddyKit. Dette er leksjon 2 av 3. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Lær Rust-programmering, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Lær Rust-programmering inneholder totalt 3 leksjoner.

Hva er innvendig muterbarhet?

I Rust hindrer lånereglene vanligvis at De har en muterbar referanse til data hvis De allerede har en uforanderlig referanse til dem. Dette sikrer datasikkerheten.

Innvendig muterbarhet er et designmønster som lar Dem endre data selv når De bare har en uforanderlig referanse til dem. Det er som et kontrollert unntak fra Rusts vanlige regler, og brukes i bestemte situasjoner.

`Cell<T>`: for Copy-typer

Typen Cell<T> gir innvendig muterbarhet for typer som implementerer Copy-trait-en (for eksempel heltall, boolske verdier og tegn). Den fungerer ved å erstatte verdien inni.

  • get(): Returnerer en kopi av verdien inni Cell.
  • set(value): Erstatter verdien inni Cell med en ny verdi.

Dette er enkelt og effektivt for små data som kan kopieres.

Bruke `Cell` til å oppdatere verdier

Her er et grunnleggende eksempel på Cell. Legg merke til at vi kan endre verdien inni Cell, selv om selve Cell er deklarert som 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>`: for typer som ikke kan kopieres

Når De trenger indre muterbarhet for typer som ikke implementerer Copy (for eksempel String, Vec eller egendefinerte strukturer), bruker De RefCell<T>.

RefCell lar Dem få muterbare referanser til de indre dataene, men håndhever Rusts regler for lån ved kjøring, ikke ved kompilering.

`RefCell`-lån ved kjøring

RefCell tilbyr metoder som returnerer smarte pekere:

  • borrow(): Returnerer en Ref (en uforanderlig smart peker). De kan ha flere uforanderlige lån samtidig.
  • borrow_mut(): Returnerer en RefMut (en muterbar smart peker). De kan bare ha ett muterbart lån om gangen.

Hvis De bryter disse reglene ved kjøring, vil programmet utføre panic!.

Bruke `RefCell` (uforanderlig lån)

Her bruker vi borrow() for å få en uforanderlig referanse til String-verdien inne i RefCell. Vi kan skrive ut innholdet.

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);
}

Bruke `RefCell` (muterbart lån)

Nå henter vi en muterbar referanse ved hjelp av borrow_mut(). Dette lar oss endre String-verdien. Merk at når s_mut er i omfang, er ingen andre lån (muterbare eller uforanderlige) tillatt.

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);
}

Kjøretids-panikk i `RefCell`

Hvis De prøver å hente et muterbart lån mens et annet muterbart lån (eller et hvilket som helst uforanderlig lån) er aktivt, vil RefCell føre til at programmet utfører panic! ved kjøring. Dette hindrer datakorrupsjon.

Kjør denne koden for å se det i praksis! Den krasjer med feilen «borrow already in use».

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.");
}

Oppsummering av `Cell` kontra `RefCell`

Valget mellom Cell og RefCell avhenger av datatypen og hvordan De trenger å samhandle med den:

  • Cell<T>: Brukes for typer som implementerer Copy. Den erstatter hele verdien og er vanligvis enklere og mer effektiv.
  • RefCell<T>: Brukes for typer som ikke implementerer Copy. Den gir referanser til de indre dataene og håndhever reglene for lån ved kjøring, slik at mer komplekse endringer blir mulig.

Rask sjekk: Cell eller RefCell?

De har en struct som må lagre en muterbar teller (u32) og en muterbar navneliste (Vec<String>), og begge må oppdateres gjennom en uforanderlig referanse til struct-en. Hvilke typer for indre muterbarhet vil De bruke for hvert felt?

Repetisjon: Indre muterbarhet

De har lært om Rusts mønster for indre muterbarhet, som gjør det mulig å endre data gjennom en uforanderlig referanse på en kontrollert og trygg måte.

  • Cell<T>: For Copy-typer; erstatter den indre verdien.
  • RefCell<T>: For typer som ikke er Copy; tilbyr muterbare og uforanderlige referanser som kontrolleres ved kjøring.
  • Hvis De bryter reglene for RefCell, oppstår en kjøretids-panikk, noe som ivaretar sikkerheten.

Disse typene er viktige for mønstre som mock-objekter, sirkulære referanser eller situasjoner der en delt uforanderlig referanse må holde oversikt over intern tilstand.

Gratis å komme i gang

Lær deg Rust med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
39
Leksjoner
144

Ofte stilte spørsmål

Er leksjonen «Intern muterbarhet: RefCell, Cell» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Lær Rust-programmering, inkludert «Intern muterbarhet: RefCell, Cell», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Lær Rust-programmering inneholder totalt 3 leksjoner.

Hva lærer jeg i «Intern muterbarhet: RefCell, Cell»?

Lær om `RefCell` og `Cell` for intern muterbarhet, slik at data trygt kan endres gjennom en uforanderlig referanse. Du øver på Lær Rust-programmering med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Lær Rust-programmering?

Ingen tidligere erfaring er nødvendig. Lær Rust-programmering på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 3.

Hvor lang tid tar leksjonen «Intern muterbarhet: RefCell, Cell»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Lær Rust-programmering-leksjonen?

Ja. Alle Lær Rust-programmering-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Smartpekere: Box, Rc og Arc
  2. Intern muterbarhet: RefCell, Cell
  3. Bekymringsløs samtidighet med tråder
← Tilbake til Lær Rust-programmering