A Rust csapata tartja a hat hetes kiadási ritmust: 2023. október 5-én, csütörtökön megjelent a Rust 1.73, ahogy azt a hivatalos blogbejegyzés is bejelentette. A release most sem hoz földindulást (nincs benne se GAT-forradalom, se async fn trait — az még jövő), de két apró, mindennapi munkát megkönnyítő változás van benne, amit érdemes ismerni.

Mi történt: a Rust 1.73 megjelenése

A szokásos módon a rustup már most letölthetővé teszi az új toolchaint, a stable csatorna automatikusan erre mutat. A release notes-ban a szokásos apróbb stabilizációk (attribútumok generikus paramétereken, cargo::rustc-check-cfg a build scriptekhez) mellett két olyan változás van, ami a napi Rust-munkádban is érzékelhető lesz.

Megjegyzés

A 1.73 még a 2021-es editiont használja alapértelmezetten, edition-váltás nem történt — ez most csak egy "sima" toolchain-frissítés, nem kell semmilyen Cargo.toml módosítást végezni miatta.

Új panic-üzenet formátum

A panic-kimenetek olvashatóbbá váltak. Ha korábban egy indexelési hiba vagy egy unwrap() egy None-on futott, a konzolon megjelenő üzenet formázása kissé tisztább lett, és a hibaüzenetek helyfeljelölése (fájl, sor, oszlop) konzisztensebb módon jelenik meg minden panic-forrás esetén — beleértve azokat a helyzeteket is, amikor a panic egy library kódból származik, nem a te saját binárisodból.

Nézzünk egy egyszerű, ma is lefordítható példát, ami panicot fog dobni futásidőben:

fn main() {
    let v: Vec<i32> = vec![1, 2, 3];
    println!("{}", v[10]);
}

Ez a kód szépen lefordul, de futás közben index-out-of-bounds panicot vág. A lényeg nem a hibaüzenet szövegének drasztikus átalakítása — a RUST_BACKTRACE=1 figyelmeztetés és a panic helye továbbra is ott van —, hanem az, hogy a formázás konzisztensebbé vált a különböző panic-forgatókönyvek (pl. Result::unwrap, index-panic, assert! makró) között. Ha van CI-pipeline-od, amely a panic-kimenetet parse-olja (pl. tesztfuttatóban), érdemes egyszer átfuttatni a szűrőlogikát az új formátumon.

Tipp

Ha eddig reguláris kifejezéssel próbáltad kiszedni a panic üzenetből a fájlnevet és a sorszámot, most ellenőrizd, hogy a regex még illik-e az új kimenetre — a formázás finomodása miatt apró eltérések lehetnek.

LocalKey<Cell> kényelmi metódusok

A másik, kisebb, de nagyon praktikus fejlesztés a std::thread::LocalKey<Cell<T>> típuson jelent meg. Eddig, ha egy thread_local! makróval definiált Cell<T>-t akartál olvasni vagy írni, mindig a .with() closure-ös mintát kellett használnod:

use std::cell::Cell;

thread_local! {
    static COUNTER: Cell<u32> = Cell::new(0);
}

fn increment_old_style() {
    COUNTER.with(|c| c.set(c.get() + 1));
}

A Rust 1.73-tól kezdve a LocalKey<Cell<T>> direktben megkapta a .get() és .set() metódusokat, így a fenti kód sokkal egyszerűbben is írható:

use std::cell::Cell;

thread_local! {
    static COUNTER: Cell<u32> = Cell::new(0);
}

fn increment() {
    COUNTER.set(COUNTER.get() + 1);
}

fn main() {
    increment();
    increment();
    println!("Számláló értéke: {}", COUNTER.get());
}

Ez a kód ma, a Rust 1.73-on lefordul és futtatva 2-t ír ki. A .with() closure-ös forma persze továbbra is elérhető és bonyolultabb, több lépéses módosításokhoz még szükséges is lehet, de a legtöbb egyszerű get/set esetén most már nem kell closure-t írnod.

Jó tudni

A kényelmi metódusok csak Cell<T>-re vonatkoznak, RefCell<T>-re nem — ott továbbra is a .with(|c| ...) mintát kell használni a borrow()/borrow_mut() hívásokhoz.

Mit jelent ez a gyakorlatban

Elsőre apró változásoknak tűnhetnek, de a napi Rust-fejlesztésben ezek pont azok az érintők, amik sokat számítanak. A thread_local! + Cell kombó tipikusan számlálókhoz, cache-flag-ekhez vagy egyszerű állapotjelzőkhöz kerül elő — gondolj csak egy per-thread request-számlálóra egy webszerverben, vagy egy egyszerű "már inicializáltam-e ezt a szálon" flag-re. Az ilyen kód most kevesebb boilerplate-tel írható, ami olvashatóbb és kevésbé hibalehetőség-forrás.

A panic-formázás javulása pedig azoknak segít a legjobban, akik nagy kódbázisokban debugolnak, vagy automatizált eszközökkel (logaggregátor, CI) dolgozzák fel a panic-kimeneteket. A konzisztensebb formátum kevesebb edge case-t jelent a parsingnál.

Emlékeztetőül: a korábban stabilizált, ma is aktívan használt eszközök — mint a GAT-ok (Generic Associated Types), a let-else szintaxis vagy a OnceCell/OnceLock — továbbra is elérhetők és jól kombinálhatók ezekkel az apró finomításokkal. Egy OnceLock-kal inicializált globális állapot és egy thread_local! Cell-lel tárolt per-thread cache együtt is remekül megáll egy nagyobb alkalmazásban.

Hogyan frissíts (rustup update)

A frissítés a szokásos módon zajlik. Ha rustup-ot használsz (amit egyébként mindenkinek javaslok, ha még nem tenné), egyetlen paranccsal naprakészre hozhatod a toolchaint:

rustup update stable

Ezután ellenőrizd, hogy tényleg az új verziót kaptad-e:

rustc --version
# rustc 1.73.0 (cc66ad468 2023-10-03)
Figyelem

Ha CI-ban rögzített toolchain-verziót használsz (rust-toolchain.toml), ne feledd frissíteni azt is, különben a build szerver a régi verzión marad, és nem fogod tudni kihasználni az új LocalKey metódusokat.

Összefoglalás

A Rust 1.73 nem egy hangos, feature-dús release, inkább a nyelv és a standard könyvtár apró, mindennapi élet minőségét javító finomhangolása. A panic-üzenetek konzisztensebbek lettek, a thread_local! Cell-ekkel dolgozó kód pedig egyszerűbben írható. Ezek pont azok a kis dolgok, amikből hat hét alatt összeadva egy sokkal kellemesebb fejlesztői élmény áll össze. Frissíts nyugodtan, kockázat nélküli, gyors upgrade.