Arbejde med unsafe Rust
Forstå, hvornår og hvordan De bruger `unsafe`-blokke til at omgå Rusts sikkerhedstjek, så FFI og operationer på lavt niveau i hukommelsen bliver mulige.
Arbejde med unsafe Rust er en gratis Lær at programmere i Rust-lektion på CoddyKit. Dette er lektion 3 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.
Usikker Rust: En introduktion
Velkommen til Usikker Rust! Rust er kendt for sine garantier for hukommelsessikkerhed, men der findes særlige situationer, hvor du kan få brug for at omgå nogle af disse kontroller.
Nøgleordet unsafe i Rust giver dig netop denne mulighed. Det er ikke en måde at skrive "dårlig" kode på, men et værktøj til avancerede anvendelser, hvor du har brug for mere direkte kontrol over hukommelse eller hardware.
De fem usikre superkræfter
Når du bruger en unsafe-blok, får du adgang til fem særlige handlinger, som Rust-compileren normalt forhindrer:
- Fjernreferér rå pointere: Få direkte adgang til hukommelsesadresser.
- Kald
unsafe-funktioner eller -metoder: Udfør funktioner med forudsætninger, som compileren ikke kan kontrollere. - Implementer
unsafe-traits: Erklær, at din type overholder bestemte invariansbetingelser. - Få adgang til eller ændr mutable statiske variabler: Del mutable tilstand globalt, hvilket kan medføre datakapløb.
- Få adgang til felter i
unions: Læs fra en union, som måske ikke har den gyldige type for de aktuelle data.
Fjernreference af rå pointere
Rå pointere er hukommelsesadresser uden Rusts sædvanlige sikkerhedsgarantier. Du kan oprette dem ud fra referencer (&T, &mut T), men det kræver en unsafe-blok at fjernreferere dem.
Det betyder, at du som programmør er ansvarlig for at sikre, at pointeren er gyldig og peger på allokeret hukommelse.
fn main() {
let mut num = 5;
let r1 = &num as *const i32; // Immutable raw pointer
let r2 = &mut num as *mut i32; // Mutable raw pointer
unsafe { // The `unsafe` block starts here
println!("r1 points to: {}", *r1);
*r2 = 10; // Modify data through mutable raw pointer
println!("r2 points to: {}", *r2);
} // The `unsafe` block ends here
println!("Num is now: {}", num);
}Kald af usikre funktioner
Nogle funktioner er markeret som unsafe fn. Det betyder, at funktionen har forudsætninger, som Rust-compileren ikke kan garantere. En funktion kan f.eks. forvente en gyldig hukommelsesadresse, men kan ikke kontrollere den.
Kald af sådanne funktioner skal omsluttes af en unsafe-blok, hvilket angiver, at du som kalder sikrer, at alle forudsætninger er opfyldt.
unsafe fn dangerous_operation() {
println!("This operation could be dangerous if preconditions aren't met!");
}
fn main() {
println!("Attempting a dangerous operation...");
unsafe { // Calling an unsafe function requires `unsafe`
dangerous_operation();
}
println!("Operation completed.");
}Mutable statiske variabler
Rust forhindrer som standard global mutable tilstand for at undgå datakapløb. Du kan dog erklære mutable statiske variabler ved hjælp af static mut.
Det betragtes som unsafe at tilgå eller ændre disse variabler, fordi flere tråde kan forsøge at tilgå dem samtidigt, hvilket kan føre til udefineret adfærd. Du er selv ansvarlig for korrekt synkronisering.
static mut COUNTER: i32 = 0; // A mutable static variable
fn add_to_counter(inc: i32) {
unsafe { // Modifying `static mut` requires `unsafe`
COUNTER += inc;
}
}
fn main() {
add_to_counter(5);
unsafe { // Reading `static mut` also requires `unsafe`
println!("COUNTER after first add: {}", COUNTER);
}
add_to_counter(10);
unsafe {
println!("COUNTER after second add: {}", COUNTER);
}
}Implementering af usikre traits
Nogle traits i Rust er markeret som unsafe trait. Det betyder, at en implementering af dem kræver, at bestemte invariansbetingelser overholdes, som compileren ikke kan kontrollere.
Et almindeligt eksempel er traitsene Send og Sync, som handler om trådsikkerhed. Hvis du implementerer et unsafe trait manuelt, skal du bruge unsafe impl Trait for Type og garantere dets sikkerhedsegenskaber.
For de fleste begyndere møder du dette sjældnere, fordi Rust ofte håndterer det automatisk eller via sikre abstraktioner.
Adgang til unionfelter
En union er en særlig type, der på et givet tidspunkt kan indeholde en værdi fra *én* af sine varianter, mens alle varianter deler den samme hukommelsesplacering. Den minder om C-unioner.
Det kræver en unsafe-blok at tilgå et felt i en union, fordi compileren ikke kan vide, hvilket felt der er aktivt. Læsning fra et inaktivt felt kan føre til udefineret adfærd eller fejlfortolkning af data.
union Data {
integer: u32,
float: f32,
}
fn main() {
let mut d = Data { integer: 42 }; // Initialize with an integer
unsafe {
// Accessing 'integer' is safe here
println!("Integer value: {}", d.integer);
// Accessing 'float' is unsafe, as 'integer' was initialized.
// This would interpret the integer's bits as a float.
// println!("Float value (unsafe): {}", d.float);
}
d.float = 3.14; // Now initialize with a float
unsafe {
// Accessing 'float' is safe now
println!("Float value: {}", d.float);
}
}Praktiske scenarier for usikker kode
Selvom unsafe bør bruges sparsomt, er det afgørende til flere avancerede programmeringsopgaver:
- Foreign Function Interface (FFI): Interaktion med kode skrevet i andre sprog (f.eks. C/C++-biblioteker).
- Ydelsesoptimering: I nogle tilfælde kan det give små ydelsesforbedringer i kritiske sektioner at omgå Rusts kontroller (men mål først!).
- Systemprogrammering på lavt niveau: Skrivning af operativsystemer, enhedsdrivere eller indlejrede systemer.
- Opbygning af sikre abstraktioner: Implementering af sikre datastrukturer eller API'er oven på usikre primitiver (f.eks. hvordan
Vecer bygget).
Dit ansvar ved brug af unsafe
Når du bruger unsafe, påtager du dig ansvaret for manuelt at opretholde Rusts sikkerhedsgarantier. Det betyder:
- At sikre, at hukommelsen er gyldig og korrekt justeret.
- At forhindre datakapløb ved arbejde med delt mutable tilstand.
- At undgå hængende pointere eller fejl på grund af brug efter frigivelse.
- At sikre, at alle funktionsforudsætninger er opfyldt.
Forkert brug af unsafe kan føre til udefineret adfærd, som er den værste slags fejl og kan være meget vanskelig at fejlsøge.
Tjek af viden om unsafe
Hvilken af følgende handlinger kræver en unsafe-blok i Rust?
Opsummering: Usikker Rust
Du har lært om Usikker Rust, en effektiv funktion, der giver dig mulighed for at omgå nogle af Rusts sikkerhedskontroller på kompileringstidspunktet i bestemte, avancerede scenarier.
Husk, at unsafe ikke slår borrow-checkeren helt fra, men flytter ansvaret for hukommelsessikkerhed og invariansbetingelser fuldstændigt over på dig som programmør. Brug det med omtanke og stor forsigtighed, typisk til FFI, optimeringer på lavt niveau eller opbygning af sikre abstraktioner.
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 “Arbejde med unsafe Rust” gratis?
Ja — alle 3 lektioner i læringssporet Lær at programmere i Rust, inklusive “Arbejde med unsafe Rust”, 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 “Arbejde med unsafe Rust”?
Forstå, hvornår og hvordan De bruger `unsafe`-blokke til at omgå Rusts sikkerhedstjek, så FFI og operationer på lavt niveau i hukommelsen bliver mulige. 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 3 af 3.
Hvor lang tid tager lektionen “Arbejde med unsafe Rust”?
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
- Deklarative makroer (`macro_rules!`)
- Procedurelle makroer: derive og funktioner
- Arbejde med unsafe Rust