Mi az a Rust? Út a biztonságos, gyors és könnyű szoftverfejlesztéshez

A Rust nevű programozási nyelv egyedi megközelítése jobb kódhoz vezet kevesebb kompromisszummal, mint a C, C++, Go és társai esetében.


"Gyors, biztonságos, könnyű használni – ebből kettőt választhatsz." Egy jó ideje már ez volt a helyzet a szoftverfejlesztés terén. A kényelmet és biztonságot előnyben részesítő nyelvek általában lassúak (lásd Python). Amelyik pedig a teljesítményre fekteti a hangsúlyt, azzal általában nehéz dolgozni és könnyű vele lábon lőni magad (lásd C vagy C++).

Lehetséges lenne egy olyan nyelv, mely mind a három tulajdonságot magában hordozza? És ami még fontosabb, rá tudnánk venni a világot, hogy használja? A Rust programozási nyelv, melyet eredetileg Graydon Hoare hozott létre, és jelenleg a Mozilla Research támogatja, egy pontosan erre irányuló próbálkozás. (A Google Go nyelvnek is hasonló ambíciói vannak, de a Rust célja, hogy a lehető kevesebb engedményt tegyen a teljesítmény rovására.)

A Rustot egy gyors, biztonságos és relatíve könnyű programozási nyelvnek szánják. Emellett szeretnék, ha széleskörben elterjedne, és nem csak egy kíváncsiságból vagy mellékesen használt nyelvvé válna a versenyben. Rengeteg jó indok támasztja alá, hogy miért van szükség egy nyelvre, ahol a biztonság azonos fontossági szinten áll a gyorsasággal és a fejlesztési teljesítménnyel. Végül is borzasztó mennyiségű szoftver létezik – és némelyik kritikus infrastruktúrát hajt – melyeket olyan nyelv használatával hoztak létre, amelyben a biztonság nem az elsődleges szempont.


A Rust programozási nyelv előnyei

A Rust a Mozilla kutatási projektjeként kezdte, hogy újraimplementálják segítségével a Firefox böngésző kulcsfontosságú komponenseit. Volt néhány ok, mely ehhez a döntéshez vezetett: a Firefox megérdemelte, hogy jobban kihasználja a modern, többmagos processzorokat; és a puszta tény, hogy a böngészőknek mindenhol elérhetőnek kell lenniük maga után vonja, hogy biztonságosan használhatónak is kell lenniük.

Ugyanakkor ezekre az előnyökre minden szoftvernek szüksége van, nem csak a böngészőknek, így a Rust nyelvi projektté fejlődött az eredeti böngészőprojektből. A Rust a következő tulajdonságok segítségével valósítja meg a biztonságos, gyors és könnyű használatot:

Egy Rust kód több platformon keresztül fordul le natív gépi kóddá. A bináris fájlok önállóak, futási idő nélkül, és a célja, hogy a generált kód olyan jól teljesítsen, mint egy hasonló C vagy C++ kód.


A Rust nem fog nem biztonságos memóriakezelést megkísérlő programokat lefordítani. A legtöbb memóriahibát felfedezik a program futása közben. A Rust szintaxisa és nyelvi elemei biztosítják, hogy a más nyelvekben gyakori memóriával kapcsolatos problémákkal – null vagy dangling pointerek, data race és társai – ne is futhasson le a program. A fordító megjelöli ezeket a hibákat, és kényszeríti a programozót, hogy javítsa ki, mielőtt egyszer is lefuthatna.


Szigorú szabályokkal irányítja a memóriakezelést, és ezt a rendszert egy ownershipnek („birtoklás”) nevezett metaforával fejezik ki. Bármilyen adott értéket csupán egy változóval lehet „birtokolni”, fogni vagy manipulálni egyszerre.

A birtoklás objektumok közti átvitelét szigorúan a compiler irányítja, így futtatáskor nincsenek váratlan memória-allokációs hibák. Az ownership megközelítés emellett azt is jelenti, hogy nincs szemétgyűjtési memóriakezelés, mint a Go vagy C# esetén. (Ez teljesítménybeli javulást is ad a nyelvnek.) Egy Rust-ban írt program minden memóriadarabkája követve van, és automatikusan szabadul fel az ownership metaforán keresztül.


A nyelv egy bizonyos mértékig megengedi neked, hogy veszélyesen élj. A Rust biztonságát részben fel tudod függeszteni, ha valahol közvetlenül kell memóriát manipulálnod, például pointert dereferálni C/C++ módjára. A kulcsszó a részben, mivel a memóriabiztonsági tevékenységeit sosem tudod teljesen kikapcsolni. De még így is, a gyakoribb felhasználási esetekben szinte soha nem kell kikapcsolnod a biztonsági övet, így az eredmény egy szoftver, mely alapértelmezetten biztonságosabb.


A biztonsági és integritási funkciói nyilvánvalóan nem érnek sokat, ha nem használják. Ezért a Rust fejlesztői és a közössége megpróbálta a lehető leghasznosabbá és legbarátságosabbá tenni az új fejlesztők számára.

Minden, ami Rust bináris fájlok létrehozásához kell, egyetlen csomagban elérhető. Külső complierekre, mint például a GCC, csak akkor van szükség, ha a Rust ökoszisztémán kívüli komponenseket fordítasz (mint például egy C könyvtár). Emellett a Microsoft Windows felhasználók sem másodlagosak; a Rust eszköztára ugyanannyira képes ott, mint Linuxon vagy MacOS-en.


Mindhárom jelentős platformon működik: Linux, Windows és MacOS. És ezen túl még másokat is támogat. Ha cross-compile a cél, vagy az általad jelenleg futtatott architektúrától vagy platformtól különbözőre szeretnél bináris fájlokat létrehozni, akkor egy kicsivel több dolgod lesz, de a Rust egyik fő célja, hogy csökkentse az ehhez szükséges teendők mennyiségét. És bár a jelenlegi platformok nagy részén fut, a megalkotóinak nem az a célja hogy mindenhol fusson – csak az épp népszerűeken, és ott, ahol nem kell túl sok kompromisszumot kötni érte.


Kevés fejlesztő akar elkezdeni egy új nyelvvel dolgozni, ha annak kevesebb vagy épp gyengébb funkciói vannak, mint amit megszokott. A Rust natív funkciói összehasonlíthatók a C++-szal: makrók, generikus programozás, pattern matching és kompozíció – ezek mind megtalálhatók benne.


A Rust nagyobb küldetéseinek egy része a C és C++ fejlesztők meggyőzése, hogy ezek helyett a Rustot használják, amikor csak lehet. De a C és C++ használói elvárják egy tisztességes standard library elérését – használni akarnak konténereket, gyűjteményeket és iterátorokat, string manipulációkat végrehajtani, folyamatokat és szálakat kezelni, hálózatokat és fájlokat kezelni, stb. A Rust képes minderre, és még sok másra a könyvtárában. Mivel cross-platform használatra tervezték, így a könyvtára csak olyanokat tud tartalmazni, melyeket megbízhatóan lehet ezek között átvinni. Az adott platformon specifikus függvényeket, mint például a Linux epoll-ja, harmadik féltől származó könyvtárak függvényeivel kell támogatni, mint a libc, mio vagy tokio.

De a standard könyvtára nélkül is lehet a Rustot használni. Egy gyakori oka ennek, hogyha olyan bináris fájlokat akarunk létrehozni, melyek nem függenek egyik platformtól sem – pl. egy beágyazott rendszer vagy egy OS kernel.


Egy nyelv hasznosságának egyik mérőszáma, hogy mennyi mindent lehet véghez vinni vele egy harmadik fél segítségével. A Cargo, a Rust könyvtárak (más néven „crates = ládák”) hivatalos raktára, pár tízezer ilyen könyvtárat listáz. Ezek egy tisztes mennyisége API binding a gyakori könyvtárakkal vagy keretrendszerekkel, hogy a Rust velük is használható legyen. Azonban a Rust közössége még nem látta el az oldalt részletes leírásokkal és rangsorral a ládák minőségéről és hasznosságáról, szóval még nem lehet megmondani, hogy mi működik és mi nem a kipróbálása, vagy a közösség megkérdezése nélkül.


Újfent, nem sok fejlesztő akar olyan nyelvvel dolgozni, melynek kicsi a támogatottsága – vagy épp nincs is egyáltalán – az általa használt fejlesztői környezetben. Pont ezért vezette be nemrég a Rust a Rust Language Server-t, mely élő feedbacket biztosít a Rust compilertől a különböző fejlesztői környezeknek, mint például a Microsoft Visual Studio Code.


A Rust nyelv hátrányai

Természetesen a rengeteg vonzó, hatásos és hatékony képességei mellett van egy-két hátránya is. Ezen akadályok némelyike elgáncsolja mind az új, mind a régi Rust felhasználókat.


A Rust még mindig egy fiatal nyelv, hiszen az 1.0-s verziót mindössze 2015-ben hozta ki. Így míg a nyelv központi szintaxisának nagy része már le lett fixálva, ekörül rengeteg dolog még mindig változékony.

Az aszinkron folyamatok, csak hogy egy példát hozzunk, még mindig nincsenek jól reprezentálva a nyelv szintaxisában. A megoldás már úton van az implementálásra az async és az await kulcsszavak segítségével.


Ha ki kell választani a Rust legproblematikusabb aspektusát, az az, hogy milyen nehéz lehet egy-egy metaforáját megfejteni. Birtoklás, kölcsönzés, és a Rust többi memóriakezelési kifejezése mindenkit elbuktatnak az első alkalommal. Sok újdonsült Rust programozó gyakori szavajárása a „fighting the borrow checker”, ahol elsőkézből megtapasztalják, milyen aprólékosan külön tartja a compiler a változtatható és a megváltoztathatatlan dolgokat.


A nehézségek egy része abból fakad, ahogy a Rust metaforái egy bőbeszédűbb kódot eredményeznek, más nyelvekhez képest. Például a string konkatenáció nem mindig olyan egyértelmű, hogy string1+string2. Az egyik objektum lehet megváltoztatható, de a másik nem. A Rust hajlamos arra, hogy a programozó oldja fel ezeket a szituációkat, és ne a compilernek kelljen kitalálni.

Még egy példa: hogyan dolgozik együtt a Rust és a C/C++. Az idő többségében a Rustot arra használják, hogy csatlakoztassák a meglévő C vagy C++ könyvtárakhoz; csak kevés C és C++ projektet írnak teljesen újra. í8De amikor mégis, akkor általában fokozatosan írják újra.)


A nyelv útja

A Rust csapata ezen hibák nagy részéről tud, és a javításukon dolgozik. Erre egy példa: hogy könnyebben lehessen C-vel és C++-szal együtt dolgozni, a csapat azt kutatja, érdemes-e kibővíteni a bindgen és a hozzá hasonló projekteket, melyek automatikusan Rust bindingot generálnak a C kódhoz. Emellett tervben van a kölcsönzés és az élettartam rugalmasabbá és könnyebben érthetővé tétele is.

Ennek ellenére a Rust eléri a céljait egy biztonságos, konkurens és praktikus nyelv létrehozásában, ahogy más nyelvek nem voltak képesek, és mindezt olyan módon, mely kiegészíti a fejlesztők eddigi munkáját.


(Forrás)


***

Ha Te is kreatív, kihívásokkal teli mérnök állást keresel minõségi munkáltatónál, jó helyen jársz, mert a Schönherz Bázis épp azért jött létre, hogy Neked segítsen.
Gyere, nézz szét aktuális állásaink között!