Rugină (limbaj de programare)

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare
Rugini
limbaj de programare
Rust limbaj de programare black logo.svg
Autor Inițial Graydon Hoare, apoi Rust Project Developers, finanțat de Fundația Mozilla
Data de origine 2010
Ultima versiune 1.54.0 (29 iulie 2021)
Utilizare scop general
Paradigme compilat, imperativ, structurat, funcțional, orientat spre obiect
Tastare static, puternic, dedus, nominal, liniar
Extensii comune .rs, .rlib
Influențată de Alef , C # , C ++ , Cyclone , Erlang , Haskell , Hermes, Limbo , Newsqueak, NIL, OCaml , Ruby , Scheme , Standard ML , Swift
A influențat C # 7, Elm, Idris, Swift , Zig
Implementare referință
Implementare [1]
Sistem de operare Windows , Mac OS , Linux
Licență MIT / Apache 2
Site-ul web www.rust-lang.org/

Rust este un limbaj de programare compilat , multi-paradigmatic, de uz general, dezvoltat de Mozilla Research, în colaborare cu comunitatea open-source. Acesta își propune să fie un limbaj eficient, sigur și adecvat pentru dezvoltarea software-ului de sistem concurent. Este conceput pentru a susține paradigme de programare imperative-procedurale , funcționale și orientate spre obiecte .

Limbajul a apărut dintr-un proiect personal al angajatului Mozilla Graydon Hoare. Sprijinul Mozilla pentru proiect a început în 2009 și a fost anunțat în 2010. În același an, compilatorul în sine, scris inițial în OCaml, a început să fie rescris în Rust. Acest compilator, cunoscut sub numele de rustc , a reușit să se compileze în 2011. Ca un back-end, folosește cadrul open source LLVM .

Prima versiune a compilatorului Rust a avut loc în ianuarie 2012. Versiunea 1.0, prima versiune stabilă, a avut loc pe 15 mai 2015.

Deși dezvoltarea sa este susținută de Mozilla, este un proiect deschis comunității open-source care contribuie activ. Designul limbajului a fost rafinat de experiența utilizării acestuia în dezvoltarea motorului de browser web Servo și a compilatorului rustc .

Într-un sondaj din 2016 realizat în rândul dezvoltatorilor Stack Overflow , Rust s-a clasat pe primul loc ca „Cel mai iubit limbaj de programare” [1] (în italiană, cel mai popular limbaj de programare). Această poziție a fost confirmată și în sondajele din 2017 [2] , 2018 [3] , 2019 [4] și 2020 [5] .

Se crede că limba își ia numele de la numele englezesc al ruginii , o specie de ciuperci care atacă frunzele plantelor [6] .

Proiecta

Scopul lui Rust este de a fi un limbaj bun pentru crearea unor sisteme complexe extrem de sigure, chiar dacă acestea sunt multithread. Acest lucru a condus la un set de caracteristici care subliniază performanța, controlul alocării memoriei, securitatea și concurența.

În ceea ce privește performanța, fiecare program tipic scris în Rust are o securitate mai mare la scrierea în memorie decât C ++, încercând să păstreze aceeași viteză a acestuia din urmă pentru majoritatea aplicațiilor [7] . Cu toate acestea, timpii de compilare sunt mai mari.

În ceea ce privește alocarea memoriei, fiecare tip folosește un număr de biți definit de limbă și are o aliniere definită de programator, iar colectarea gunoiului nu este utilizată, permițând o repartizare deterministă a memoriei.

În ceea ce privește securitatea, limbajul interzice construcțiile cu un comportament nedefinit, cum ar fi citirea variabilelor nescrise, accesarea dincolo de limitele matricei, dereferențierea pointerilor nuli sau invalizi și utilizarea iteratorilor invalidați.

În ciuda absenței colectării gunoiului, memoria alocată dinamic este repartizată automat datorită faptului că compilatorul introduce instrucțiunile corespunzătoare atunci când variabilele ies din domeniul său de aplicare. Scurgerile de memorie sunt considerate sigure, dar pot apărea numai în situații particulare: de exemplu, apelând funcțiile de bibliotecă adecvate ( Box::leak , std::mem::forget , ...) sau prin crearea de cicluri de pointer numărate de referință ( Rc , Arc ).

În ceea ce privește securitatea concurenței, limba împiedică operațiile concurente cu rezultate nedeterminate, cum ar fi accesul simultan la scriere la aceeași variabilă.

Sintaxa lui Rust seamănă cu cea a limbajului C pentru utilizarea parantezelor pentru a cuprinde structuri sau blocuri de instrucțiuni, pentru operatori aritmetici și logici și pentru cuvinte cheie de control al fluxului if , else , for , în while , break , continue și return . Tipurile primitive de rugină sunt analoage tipurilor de C, deși cu aproape toate numele diferite. Cu toate acestea, semantica Rust este destul de diferită de cele ale C și C ++.

Sistemul de tip acceptă o construcție numită „trăsătură”, inspirată din limbajul Haskell , care permite moștenirea interfeței multiple, dar nu moștenirea implementării. Această moștenire poate fi fie statică, analogă cu trăsăturile șablonului C ++, fie dinamică, analogă cu funcțiile virtuale C ++.

Rust are inferență de tip, adică ori de câte ori declarați o variabilă locală, este opțional să declarați tipul acesteia. Acesta din urmă este derivat din expresia de inițializare sau din instrucțiunile de atribuire ulterioare acelei variabile.

Nu este obligatoriu inițializarea variabilelor. Cu toate acestea, se generează o eroare de compilare dacă se utilizează o variabilă înainte de a primi o valoare sau dacă i se atribuie valori de diferite tipuri.

Clasele (numite „structuri”) și funcțiile pot fi parametrizate prin tipuri similare șabloanelor C ++. Cu toate acestea, aceste tipuri parametrice trebuie să fie legate de trăsături pentru a-și utiliza metodele sau operatorii.

Rugina diferă de multe alte limbaje orientate obiect pentru următoarele opțiuni de proiectare:

  • folosim conceptele de „proprietate” a obiectelor și „împrumut” a obiectelor pentru a decide ce instrucțiuni pot citi un obiect și care îl pot scrie;
  • programatorului i se permite, și uneori este necesar, să specifice o „durată de viață” asociată cu obiectele gestionate de pointer pentru a decide când astfel de obiecte urmează să fie distruse;
  • nu se folosește conceptul de excepție;
  • moștenirea de implementare nu este utilizată, adică fiecare clasă poate moșteni doar de la interfețe, nu de la alte clase;
  • clasele nu sunt obiecte, adică nu există metaclase;
  • clasele nu au moștenire implicită de la o interfață comună;
  • supraîncărcarea funcției nu este utilizată, adică în același scop funcțiile trebuie să aibă nume diferite;
  • nu se utilizează nici reflecția, nici evaluarea expresiilor în timpul rulării ( eval ).

Istorie

Stilul sistemului de obiecte s-a schimbat considerabil între versiunile 0.2, 0.3 și 0.4 din Rust. Versiunea 0.2 a introdus clase. Versiunea 0.3 a adăugat câteva caracteristici, inclusiv destructori și polimorfism prin utilizarea interfețelor. În Rust 0.4, trăsăturile au fost adăugate ca mijloc de furnizare a moștenirii, interfețele au fost unificate în trăsături și apoi eliminate ca o caracteristică separată. Clasele au fost, de asemenea, eliminate, înlocuite de o combinație de structuri și implementări.

Începând cu versiunea 0.9 și până la versiunea 0.11, Rust avea două tipuri de indicatori, ~ și @ , care simplificau modelul de memorie internă. Primul dintre aceste tipuri de pointer a fost înlocuit de funcția de bibliotecă Box , iar al doilea, care a folosit colectarea gunoiului, a fost eliminat.

Deoarece principalul motiv pentru care nimeni nu a adoptat Rust a fost faptul că limbajul a devenit incompatibil cu versiunea anterioară cu fiecare modificare a versiunii, la lansarea 1.0, prima versiune stabilă, s-a promis că următoarele versiuni 1.x vor fi compatibil cu acesta.

La 8 februarie 2021, dezvoltarea limbajului trece oficial sub controlul Fundației Rust [8] , o organizație non-profit independentă finanțată de Mozilla , Microsoft , Google , AWS și Huawei .

Utilizare

Siguranța, competiția și caracteristicile de înaltă performanță ale Rust au atras interesul multor realități diferite, conducând limba să fie folosită în diferite domenii.

Aici sunt cateva exemple:

  • Dezvoltare web: scrierea codului WebAssembly ; dezvoltarea de aplicații web cu cadrul Rocket .
  • Aplicații server: Dropbox a folosit Rust pentru a-și implementa propriul back-end, separându-se de serviciile Amazon [9] ; Cloudflare a folosit Rust pentru a implementa un interpretor TPC / IP [10] de înaltă performanță.
  • Dezvoltarea jocurilor video: scrierea motoarelor de jocuri, cum ar fi Bevy ; studioul Ready at Dawn folosește Rust ca limbaj principal pentru dezvoltarea de noi jocuri [11] .
  • Sisteme de operare : implementarea de drivere noi în nucleul Linux [12] ; dezvoltarea Redox , un sistem de operare asemănător Unix scris în întregime în Rust; Google Fuchsia conține părți scrise în Rust și acceptă limba pentru scrierea aplicațiilor native [13] .
  • Dezvoltare încorporată : scrierea și compilarea codului în format binar pentru nucleul ARM Cortex-M [14] și alte ținte, fără sprijinul unui sistem de operare.

Exemple

Buna lume :

 fn main () {
    println! ( „Bună ziua, lume!” );
}

Trei versiuni ale funcției factoriale , utilizând stilurile recursive , iterative și funcționale , respectiv:

 // Sucursalele din această funcție prezintă valori returnate
// fără a utiliza cuvântul „return”, care este opțional, pentru a obține
// un stil mai „funcțional”. Rețineți absența punctului și virgula după
// declarații doar pentru a indica faptul că aceasta este valoarea returnată.
// Spre deosebire de limbaje C și limbaje similare, Rust construiește „dacă”
// este o expresie în loc de o afirmație și, prin urmare, are propria sa valoare
// returnează, în mod similar cu operatorul ternar '?:' al lui C.
fattoriale_ricorsivo fn (n: u32) -> u32 {
    dacă n <= 1 {
        1
    } altceva {
        n * factorial_recursiv ( n - 1 )
    }
}

fattoriale_iterativo fn (n: u32) -> u32 {
    // Variabilele sunt declarate cu cuvântul „let”.
    // Cuvântul „mut” permite mutarea acestor variabile.
    lăsa mut the = 1 u32 ;
    lăsa mut rezultat = 1 u32 ;
    in timp ce the < n {
        the + = 1 ;
        rezultat * = i ;
    }
    // Returnare explicită, spre deosebire de funcția anterioară.
    // Aceasta este considerată „slabă”. Cuvântul cheie returnat este acceptat
    // numai pentru ieșirea timpurie dintr-o funcție.
    întoarcere rezultat ;
}

fattoriale_funzionale fn (n: u32) -> u32 {
    // Iteratorii au diverse metode de transformare.
    // | acumul, x | pornește o funcție anonimă (lambda sau „închidere” conform
    // terminologia utilizată de comunitatea Rust).
    // Optimizările precum extinderea în linie fac această versiune
    // la fel de eficient ca iterativ.
    ( 1 .. n ). ori ( 1 , | acumul , x | acumul * ( x + 1 ))
}

fn main () {
    println! ( „Rezultat recursiv: {}” , factorial_recursiv ( 10 ));
    println! ( „Rezultat iterativ: {}” , factorial_ iterativ ( 10 ));
    println! ( „Rezultat funcțional: {}” , functional_factorial ( 10 ));
}

O simplă demonstrație a potențialului competitiv al Rust:

 utilizare std :: thread ;

// Această funcție creează și pornește zece fire concurente.
// Pentru a verifica acest lucru, rulați programul de mai multe ori și respectați ordinea
// neregulat cu care imprimă fiecare fir.
fn main () {
    // Acest șir este imuabil,
    // prin urmare poate fi accesat în siguranță prin mai multe fire.
    lăsa Salut = „Bună ziua” ;

    lăsa mut fire = Vec :: new ();
    // buclele „pentru” funcționează cu orice tip implementați
    // trăsătura „Iterator”.
    pentru num în 0 .. 10 {
        fire . push ( thread :: spawn ( mutare || {
            // 'println!' este un macro care verifică static
            // șirul de format. Macro-urile sunt structurale
            // (ca în Scheme), non-textual (ca în C).
            println! ( „{} din numărul de fir {}” , salut , num );
        }));
    }

    // Așteptați terminarea fiecărui fir înainte de a ieși din program.
    pentru fir în fire {
        fir . join (). desface ();
    }
}

Iată o demonstrație a indicatoarelor inteligente unice furnizate de Rust, împreună cu uniunile și metodele etichetate:

 utilizare Număr întreg :: { Nod , Gol };

// Acest program definește o structură și implementează date recursive
// metode pe el. Structurile de date recursive necesită
// un nivel de indirecție, care este dat aici de un indicator unic,
// construit prin constructorul „Box :: new”. Acestea sunt analoage
// la tipul de bibliotecă standard C ++ „std :: unique_ptr”,
// deși cu garanții de securitate mai statice.
fn main () {
    lăsa listă = Integer :: new (). prependi ( 3 ). prependi ( 2 ). prependi ( 1 );
    println! ( "Suma tuturor valorilor din listă: {}." , listă . sumă ());
    println! ( "Suma tuturor valorilor dublate din listă: {}." ,
        listă . multiplicați_by ( 2 ). sumă ());
}

// „enum” definește o variantă (uniune etichetată), care în timpul rulării
// poate fi unul dintre mai multe cazuri.
// Aici un obiect de tip „întreg” o nu conține nicio valoare,
// adică este „Blank” sau conține un număr întreg și un pointer
// către un alt obiect de tip „Întreg”, adică merită „Nodo” cu al său
// două câmpuri poziționale.
enum WholeList {
    Nod ( i32 , Caseta < Lista întreagă > ),
    Gol
}

// Un bloc „impl” vă permite să adăugați definiții de metode la un tip.
// Aici definim metodele pentru tipul „întreg”
// 'new', 'prepend', 'add' și 'multiply_by'.
impl Întreaga Listă {
    fn nou () -> Caseta < Lista întregi > {
        Casetă :: nou ( gol )
    }

    fn prependi ( self , valoare : i32 ) -> Caseta < Lista întregi > {
        Casetă :: nou ( Nod ( valoare , Casetă :: nou ( auto )))
    }

    fn sum ( & self ) -> i32 {
        // expresiile „potrivire” sunt modalitatea tipică de a face
        // potrivire de model. Înlocuiți construcția „comutator”
        // decât limbajul C, dar sunt mult mai puternici.
        Meci * sinele {
            Nod ( valoare , ref urmator ) => valoare + următorul . sumă (),
            Gol => 0
        }
    }

    fn multiplică_by ( & auto , n : i32 ) -> Caseta < Lista întregi > {
        Meci * sinele {
            Nod ( valoare , ref urmator ) =>
                Casetă :: nou ( Nod ( valoare * n , următorul . multiplicate_by ( n ))),
            Gol => Casetă :: nou ( gol )
        }
    }
}

Notă

  1. ^ Rezultatele sondajului pentru dezvoltatorii Stack Overflow 2016 , pe Stack Overflow . Adus la 17 iunie 2016 .
  2. ^ Stack Overflow Developer Survey 2017 , în Stack Overflow . Adus la 30 mai 2017 .
  3. ^ Stack Overflow Developer Survey 2018 , în Stack Overflow . Adus la 16 martie 2018.
  4. ^ Stack Overflow Developer Survey 2019 , în Stack Overflow . Adus pe 12 aprilie 2019 .
  5. ^ (EN) Ben Popper Director de conținut, Rezultatele sondajului pentru dezvoltatori din 2020 sunt aici! , pe Stack Overflow Blog , 27 mai 2020. Adus pe 27 mai 2020 .
  6. ^ Internet arheology: the definitiv, end-all source for why Rust is named "Rust" • / r / rust , pe reddit . Adus la 17 iunie 2016 .
  7. ^ ( RO ) 0.21 Cât de rapid este rugina? , în The Rust Project Developers . Adus la 4 mai 2021.
  8. ^ (EN) Rust Foundation , pe foundation.rust-lang.org. Adus la 12 februarie 2021 .
  9. ^ (EN) The Epic Story of Dropbox's Exodus From the Amazon Cloud Empire , în Wired. Adus de 18 iunie 2021.
  10. ^ (EN) Construirea de interpreți rapizi în Rust , Cloudflare of The Blog, 4 martie 2019. Accesat la 18 iunie 2021.
  11. ^ (EN) Rust for Game Development , pe GameFromScratch.com, 31 iulie 2018. Accesat la 18 iunie 2021.
  12. ^ [PATCH 00/13] [RFC] Suport pentru rugină , la lore.kernel.org . Adus de 18 iunie 2021.
  13. ^ (RO) Rugină | Fuchsia , pe Fuchsia . Adus de 18 iunie 2021.
  14. ^ rust-embedded / wg , Rust Embedded, 18 iunie 2021. Adus 18 iunie 2021 .

Elemente conexe

linkuri externe

Controlul autorității LCCN (EN) sh2018000672 · GND (DE) 1078438080
Informatică Portal IT : accesați intrările Wikipedia care se ocupă cu IT