# Rust

## Vad det är

Rust är ett programspråk för det arbete som traditionellt görs i C och C++, där ett program sköter
sitt eget minne och ofta länkas in i mjukvara som är skriven i andra språk. Kompilatorn översätter
koden till maskinkod i förväg. Version 1.0 tillkännagavs den 15 maj 2015 som ett språk som förenar
styrning av prestanda på låg nivå med garantier för säkerhet, nådda utan skräpsamlare eller
körmiljö, och det är just det som låter ett bibliotek i Rust ersätta ett i C.

Minnet hanteras genom ägarskap, en uppsättning regler som kompilatorn kontrollerar. Varje värde har
en enda ägare i taget, och när ägaren går ur scope släpps värdet och dess minne frigörs, vid en
punkt som bestäms när programmet kompileras snarare än när en skräpsamlare nästa gång tittar efter.
Kod som behöver ett värde utan att ta över det lånar en referens, och lånereglerna tillåter i varje
ögonblick antingen en enda muterbar referens eller hur många oföränderliga som helst, och kräver att
varje referens är giltig. Ett program som bryter mot en regel kompileras inte. Samma regler
utesluter datakapplöpningar, så två trådar som skriver till samma data utan synkronisering är ett
kompileringsfel snarare än ett fel som dyker upp då och då.

Rust saknar undantag. En funktion som kan misslyckas på ett väntat sätt returnerar ett `Result`, som
rymmer antingen ett värde eller ett fel, och i många fall kräver kompilatorn att anroparen tar hand
om felet innan koden byggs. En bugg som programmet inte kan återhämta sig från, som att läsa förbi
slutet av en array, går i stället genom makrot `panic!`.

Statisk analys är försiktig, så kompilatorn avvisar en del program som hade fungerat, och visst
arbete, som att styra hårdvara eller anropa ett annat språk, går inte att kontrollera alls. För de
fallen finns `unsafe`, som låser upp fem extra förmågor, bl.a. att avreferera en rå pekare och att
anropa en osäker funktion, vilket som standard omfattar varje funktion som deklareras från C. Det
stänger inte av lånekontrollen, den så kallade borrow checker. Det markerar de rader där
programmeraren, inte kompilatorn, går i god för minnessäkerheten, så en minnesbugg kan bara finnas
inuti ett block med `unsafe`. Rust-bokens råd är att hålla de blocken små och kapsla in dem i ett
säkert gränssnitt, och det är så delar av standardbiblioteket är byggda.

En ny kompilator släpps var sjätte vecka. Ändringar som skulle bryta befintlig kod väntar på en
utgåva, en edition, som kommer ungefär vart tredje år. Det finns fyra utgåvor, 2015, 2018, 2021 och
2024, och den senaste blev stabil den 20 februari 2025 med Rust 1.85.0. Varje programpaket anger sin
utgåva i `Cargo.toml`, varje kompilator bygger alla utgåvor som kom före den, och programpaket med
olika utgåvor länkas ihop, så ett projekt går vidare när det självt väljer. Cargo, språkets
beroendehanterare och byggverktyg, följer med språket, rustfmt håller kodstilen enhetlig, och
bibliotek från tredje part kommer som programpaket som kallas crates.

## Varför det spelar roll

I C och C++ kompileras en pekare som används efter att dess minne har frigjorts, eller två trådar
som skriver samma data, utan klagomål och fallerar senare, sporadiskt och ofta långt från orsaken.
Rust gör sådana program till kompileringsfel, och eftersom kontrollerna körs när programmet byggs
betalar det färdiga programmet ingenting för dem.

Eftersom Rust varken bär på en skräpsamlare eller en körmiljö kan kod i Rust ligga under mjukvara i
andra språk. Allt som kan anropa C kan anropa en kärna i Rust genom ett C-gränssnitt, så en enda
vältestad implementation kan betjäna klienter på flera plattformar. Rust-boken räknar upp
kommandoradsverktyg, webbtjänster, inbyggda enheter och stora delar av webbläsaren Firefox bland de
användningar som finns i produktion.

Kostnaden betalas i förväg. Koden måste formas så att kompilatorn kan se att den är säker, vilket
ofta innebär att bestämma vem som äger ett värde i stället för att skicka runt referenser fritt, och
boken säger själv att ägarskap tar tid att vänja sig vid. När kompilatorn vägrar ett program som den
inte kan verifiera är svaret oftast en annan struktur snarare än en väg runt kontrollen.

Stabiliteten är den andra halvan av överenskommelsen. Sedan 1.0 är ändringar som bryter befintlig
kod i stort sett uteslutna, så en ändring som skulle kunna bryta gammal kod kommer bara genom en
utgåva som ett programpaket självt väljer att gå över till.

## Så ser det ut i praktiken

I portföljen är Rust kärnan under
[en native meddelandeklient för macOS](/sv/portfolio/built-a-native-macos-messaging-client-in-swift-6-154/):
den vältestade kärnan i protokollet är skriven i Rust och exponerar ett C-gränssnitt, och klienten,
11 141 rader Swift i 53 filer, länkar in den som ett statiskt arkiv kompilerat från en fastlåst
uppströmsrevision. Låsningen spelar roll eftersom C-gränssnittet är kontraktet: en kärna i rörelse
ändrar kontraktet utan att en enda rad Swift ändras. Allt som C-gränssnittet returnerar har en
ägarskapsregel, och ett misstag i någon av dem ger en läcka eller en krasch utan en enda
kompilatorvarning på vägen, så en tunn wrapper äger varje pekare och varje sträng som korsar
gränsen, och inget lager ovanför den ser en rå pekare.

Att länka in den kärnan i en applikation innebär att leverera allt som den är beroende av, och det
är ämnet för
[en licensgranskning av 644 Rust-crates](/sv/portfolio/audited-644-rust-crates-for-licence-compatibility-163/).
Varje crate deklarerar sin licens som ett uttryck, och granskningen kontrollerar varje uttryck i
hela beroendegrafen mot en tillåtelselista vid varje bygge, där OR läses som ett val mellan licenser
och AND som en skyldighet att följa båda. Allt som inte matchar får bygget att fallera. Eftersom en
kontroll som aldrig har fallerat ser likadan ut som en som inte kan fallera, fick den fallera med
flit, två gånger: en gång genom att en crates licens skrevs om till ett villkor som listan avvisar,
och en gång genom att den fastlåsta kärnrevisionen flyttades utan att granskningen genererades om.
Den läser bara deklarerade metadata och är ingen juridisk rådgivning.

Den här webbplatsen har ingen egen källkod i Rust. Den möter språket på avstånd, genom Ruff, som är
skrivet i Rust och kontrollerar varje Python-skript som en commit rör.

## Var det går fel

Det mesta besväret med Rust sitter vid kanterna av det som kompilatorn kontrollerar: aritmetik i ett
optimerat bygge, gränsen mot ett annat språk och kod som kommer in med ett beroende.

**Aritmetik slår runt i ett releasebygge.** En räknare som fick panik vid ett överspill under
testningen blir i tysthet ett litet tal i produktion. I debugbyggen kontrollerar Rust
heltalsaritmetik efter överspill och får panik. Ett bygge med `--release` utelämnar kontrollen och
slår runt, så 256 i en `u8` blir 0, och boken betraktar det som ett fel att förlita sig på det
omslaget. Där ett värde kan spilla över ska beteendet väljas uttryckligen: `checked_*` returnerar
`None`, `saturating_*` stannar vid gränsen och `wrapping_*` slår runt med avsikt.

```rust
fn add_stock(on_hand: u8, delivered: u8) -> Option<u8> {
    // None när summan inte får plats, i debug- och releasebyggen lika
    on_hand.checked_add(delivered)
}
```

**Minnesbuggar kommer tillbaka vid gränsen mot C.** Ett program vars Rust-sida byggs utan en enda
varning läcker minne eller kraschar inne i ett främmande anrop. Funktioner som deklareras i ett
block med `extern` är osäkra att anropa eftersom det andra språket inte upprätthåller någon av Rusts
regler, så vem som frigör varje pekare är en konvention som kompilatorn inte kan se. Ge en enda
wrapper ansvaret för varje pekare och sträng som korsar gränsen, skriv ned varje ägarskapsregel
bredvid anropet och exponera bara ett säkert gränssnitt ovanför det.

**En panik når C och processen avbryts.** En Rust-funktion som anropas från C får panik, och i
stället för ett fel stannar hela programmet. Sedan Rust 1.81, som släpptes den 5 september 2024,
avbryter en panik som försöker lämna en funktion deklarerad med det vanliga gränssnittet `"C"` hela
processen. Gör fel till returvärden innan de når gränsen, och deklarera en funktion med `"C-unwind"`
bara där koden på andra sidan förväntar sig att stacken rullas upp.

**En rutinmässig uppdatering ändrar licensen för hela bygget.** En versionshöjning tre nivåer ned
drar in en crate vars licens produkten inte kan godta, och ingenting i bygget säger ifrån. Varje
crate deklarerar sin egen licens, och skyldigheterna läggs ihop över hela grafen. Kontrollera varje
crates uttryck mot en tillåtelselista vid varje bygge, låt allt som inte matchar få bygget att
fallera och bryt kontrollen med flit en gång för att bevisa att den slår till.

## Läs mer

- [The Rust Programming Language](https://doc.rust-lang.org/book/)
  — den officiella boken, från installation via ägarskap och felhantering till osäker kod.
- [What Is Ownership?](https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html)
  — de tre reglerna för ägarskap och hur minnet frigörs utan en skräpsamlare.
- [Unsafe Rust](https://doc.rust-lang.org/book/ch20-01-unsafe-rust.html)
  — de fem osäkra förmågorna, råa pekare och att anropa C genom `extern`.
- [The Manifest Format](https://doc.rust-lang.org/cargo/reference/manifest.html)
  — fälten `edition`, `rust-version` och `license` i `Cargo.toml`.
- [Announcing Rust 1.0](https://blog.rust-lang.org/2015/05/15/Rust-1.0/)
  — de ursprungliga målen och det stabilitetslöfte som började med 1.0.

<https://engineer.company/sv/glossary/rust/>
