Intern muterbarhet: RefCell och Cell
Lär er om `RefCell` och `Cell` för intern muterbarhet, så att data säkert kan nås muterbart via en oföränderlig referens.
Intern muterbarhet: RefCell och Cell är en gratis lektion i Lär dig programmera i Rust på CoddyKit. Detta är lektion 2 av 3. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Lär dig programmera i Rust, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Lär dig programmera i Rust innehåller totalt 3 lektioner.
Vad är inre muterbarhet?
I Rust hindrar lånereglerna vanligtvis dig från att ha en muterbar referens till data om du redan har en oföränderlig referens till den. Detta säkerställer datasäkerhet.
Inre muterbarhet är ett designmönster som låter dig ändra data även när du bara har en oföränderlig referens till den. Det fungerar som ett kontrollerat undantag från Rusts vanliga regler och används i specifika situationer.
`Cell<T>`: för typer som implementerar Copy
Typen Cell<T> tillhandahåller inre muterbarhet för typer som implementerar traitet Copy, till exempel heltal, booleska värden och tecken. Den fungerar genom att ersätta värdet inuti.
get(): Returnerar en kopia av värdet iCell.set(value): Ersätter värdet iCellmed ett nytt värde.
Det är enkelt och effektivt för små, kopierbara datamängder.
Använda `Cell` för att uppdatera värden
Här är ett grundläggande exempel på Cell. Observera hur vi kan ändra värdet i Cell trots att själva Cell har deklarerats som oföränderlig.
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>`: för typer som inte implementerar Copy
När du behöver inre muterbarhet för typer som inte implementerar Copy (till exempel String, Vec eller anpassade strukturer) använder du RefCell<T>.
RefCell gör att du kan få muterbara referenser till de inre data, men upprätthåller Rusts låningsregler vid körning, inte vid kompilering.
`RefCell`: låning vid körning
RefCell tillhandahåller metoder som returnerar smarta pekare:
borrow(): Returnerar enRef(en oföränderlig smart pekare). Du kan ha flera oföränderliga lån samtidigt.borrow_mut(): Returnerar enRefMut(en muterbar smart pekare). Du kan bara ha ett muterbart lån åt gången.
Om du bryter mot dessa regler vid körning kommer programmet att panic!.
Använda `RefCell` (oföränderligt lån)
Här använder vi borrow() för att få en oföränderlig referens till String-värdet inuti RefCell. Vi kan skriva ut dess innehåll.
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);
}Använda `RefCell` (muterbart lån)
Nu hämtar vi en muterbar referens med hjälp av borrow_mut(). Det gör att vi kan ändra String-värdet. Observera att inga andra lån (muterbara eller oföränderliga) är tillåtna när s_mut är i omfång.
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 vid körning
Om du försöker skapa ett muterbart lån medan ett annat muterbart lån (eller ett oföränderligt lån) är aktivt, får RefCell programmet att panic! vid körning. Detta förhindrar datakorruption.
Kör koden för att se hur det fungerar! Den kraschar med felet "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.");
}Sammanfattning: `Cell` jämfört med `RefCell`
Vilken av Cell och RefCell du bör välja beror på din datatyp och hur du behöver arbeta med den:
Cell<T>: Används för typer som implementerarCopy. Ersätter hela värdet och är vanligtvis enklare och mer effektiv.RefCell<T>: Används för typer som inte implementerarCopy. Tillhandahåller referenser till de inre data och upprätthåller låningsregler vid körning, vilket möjliggör mer komplexa ändringar.
Snabbtest: `Cell` eller `RefCell`?
Du har en struct som behöver lagra en muterbar räknare (u32) och en muterbar namnlista (Vec<String>), och båda måste uppdateras via en oföränderlig referens till struct. Vilka typer för inre muterbarhet skulle du använda för respektive fält?
Repetition: inre muterbarhet
Du har lärt dig om Rusts mönster för inre muterbarhet, som gör det möjligt att ändra data via en oföränderlig referens på ett kontrollerat och säkert sätt.
Cell<T>: För typer medCopy; ersätter det inre värdet.RefCell<T>: För typer utanCopy; tillhandahåller muterbara och oföränderliga referenser som kontrolleras vid körning.- Om du bryter mot reglerna för
RefCellleder det till panik vid körning, vilket säkerställer säkerheten.
Dessa typer är viktiga för mönster som mock-objekt, cirkulära referenser eller när en delad oföränderlig referens behöver hålla reda på internt tillstånd.
Lär dig Rust med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 39
- Lektioner
- 144
Vanliga frågor
Är lektionen ”Intern muterbarhet: RefCell och Cell” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Lär dig programmera i Rust, inklusive ”Intern muterbarhet: RefCell och Cell”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Lär dig programmera i Rust innehåller totalt 3 lektioner.
Vad lär jag mig i ”Intern muterbarhet: RefCell och Cell”?
Lär er om `RefCell` och `Cell` för intern muterbarhet, så att data säkert kan nås muterbart via en oföränderlig referens. Ni övar på Lär dig programmera i Rust med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Lär dig programmera i Rust?
Du behöver inga förkunskaper. Utbildningen i Lär dig programmera i Rust på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 3.
Hur lång tid tar lektionen ”Intern muterbarhet: RefCell och Cell”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Lär dig programmera i Rust-lektionen?
Ja. Varje Lär dig programmera i Rust-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Smarta pekare: Box, Rc och Arc
- Intern muterbarhet: RefCell och Cell
- Bekymmersfri samtidighet med trådar