7 motive pentru a folosi Rugina pentru următorul proiect de dezvoltare

Ești un programator interesat să învețe Rust? Pentru a te ajuta să iei o decizie, acest articol îți prezintă câteva dintre atributele distinctive ale Rust, un limbaj de programare a sistemelor extrem de apreciat.

În cadrul acestui articol, vom investiga limbajul de programare Rust, concentrându-ne pe caracteristicile sale definitorii, precum sistemul său de tip, protecția memoriei și conceptul de proprietate. De asemenea, vom oferi o listă de resurse educative care te pot ajuta în procesul de învățare al Rust.

Să pornim la drum!

Ce este Rust?

Rust se definește ca un limbaj de programare a sistemelor. Graydon Hoare, un dezvoltator, a inițiat proiectul ca un demers personal în 2006. În mai puțin de zece ani, acesta a devenit alegerea preferată pentru programarea sistemelor și aplicațiile conexe. Salariul mediu al unui programator Rust este de aproximativ 120.000 de dolari americani.

Prin urmare, dacă intenționezi să faci tranziția de la C++ la Rust sau vrei să explorezi un nou limbaj, învățarea Rust poate reprezenta o opțiune excelentă! Conform sondajului StackOverflow Developer, Rust a fost desemnat cel mai apreciat limbaj de programare, menținându-se pe această poziție timp de șapte ani consecutivi.

Sursa imagine: StackOverflow

Rust oferă performanța rapidă a limbajelor de nivel scăzut, precum C și C++, dar și siguranța oferită de limbajele de nivel înalt, cum ar fi Python.

De la proiecte renumite precum Dropbox și Firefox, până la WebAssembly și programarea încorporată, Rust este utilizat pe scară largă în toate domeniile dezvoltării software. Rust oferă suport nativ pentru gestionarea pachetelor prin intermediul Cargo.

Cargo: Instrumentul de gestionare a pachetelor pentru Rust

Cargo este managerul de pachete pentru Rust. Poți utiliza Cargo pentru a instala pachete din depozitele de cod, registrul pachetelor Rust. Pe lângă funcția de manager de pachete, care permite căutarea, instalarea și gestionarea acestora, Cargo acționează și ca un instrument de rulare a testelor, generator de documentație și sistem de compilare.

Acum că ai o perspectivă generală asupra Rust, să analizăm mai îndeaproape anumite caracteristici care îl diferențiază ca limbaj de programare a sistemelor, cu o adoptare din ce în ce mai largă.

Mesaje de eroare utile

Ca programator începător, vei întâmpina erori și vei aloca mult timp depanării codului. Mesajele de eroare și avertismentele furnizate de compilator te vor ajuta să rezolvi aceste probleme. Mesajele utile pot contribui la o depanare mai rapidă.

Un exemplu de mesaj de eroare

Când codul tău nu reușește să se compileze, Rust generează mesaje de eroare clare, care oferă explicații despre ce trebuie corectat în cod și unde se află problema.

În exemplul de mai jos, variabila num2 este definită în interiorul funcției inner(). Prin urmare, este limitată la domeniul de aplicare al acestei funcții. Dacă încerci să o accesezi în afara funcției, compilatorul va afișa o eroare:

fn main() {
      let num1 = 10;
      fn inner(){
          let num2 = 9; 
      }
      println!("Valoarea lui num2 este: {}", num2);
  }

Iar mesajul de eroare oferă informații despre ce anume trebuie rectificat.

error[E0425]: nu se poate găsi valoarea `num2` în acest domeniu
   --> src/main.rs:6:42
    |
  6 |     println!("Valoarea lui num2 este: {}", num2);
    |                                            ^^^^ ajutor: există o variabilă locală cu un nume similar: `num1`
  

Avertismente în timpul compilării

Compilatorul oferă și avertismente utile cu privire la posibile probleme în codul tău. Dacă definești variabile pe care nu le folosești ulterior în program, Rust va genera un mesaj de avertizare, ca în exemplul următor.

fn main() {
      let num1 = 10;
      let num2 = 9;
      println!("Valoarea lui num1 este: {}", num1);
  }

Aici, variabila num2 este declarată, dar nu este utilizată în altă parte.

avertisment: variabilă nefolosită: `num2`
   --> src/main.rs:3:9
    |
  3 |     let num2 = 9;
    |         ^^^^ ajutor: dacă este intenționat, adaugă un underscore ca prefix: `_num2`
    |
  

Limbaj puternic tipizat

Un alt motiv pentru a alege Rust pentru proiectele tale de dezvoltare este sistemul său de tip. Rust este un limbaj puternic tipizat, ceea ce înseamnă că nu permite coerciția de tip. Coerciția de tip este atunci când un limbaj poate transforma implicit o valoare dintr-un tip de date în altul.

De exemplu, următorul cod Python se va executa fără erori. Acest lucru se întâmplă deoarece în Python, un număr diferit de zero este evaluat ca True, astfel instrucțiunea if se execută fără probleme, chiar dacă numărul 10 este un întreg, nu un boolean.

num1 = 10
  if num1:
      num2 = 9
  print(f"num2 este {num2}")

  # Ieșire: num2 este 9

Pe de altă parte, Rust nu efectuează coerciții de tip. Următorul cod va genera, prin urmare, o eroare:

fn main() {
      let num1 = 10;
      if num1{
          let num2 = 9; 
      }
  }

Eroarea indică o nepotrivire de tip, unde era așteptat un boolean, dar s-a găsit un întreg.

eroare[E0308]: tipuri nepotrivite
   --> src/main.rs:3:8
    |
  3 |     if num1{
    |        ^^^^ așteptat `bool`, găsit întreg

Siguranța memoriei

Siguranța memoriei este o altă caracteristică a limbajului Rust, care îl face atractiv pentru programatori. Vom încerca să oferim o prezentare generală a modului în care funcționează.

Variabilele trebuie inițializate înainte de a fi folosite

În Rust, toate variabilele trebuie inițializate înainte de a fi utilizate. În limbaje precum C, următorul cod, în care num nu este inițializată, se va compila și rula fără erori. Valoarea variabilei neinițializate este o valoare aleatoare.

#include <stdio.h>

  int main(void) {
      int num;
      printf("Valoarea lui num este %d", num);
      return 0;
  }
  // Ieșire: Valoarea lui num este 0

Dacă încerci ceva similar în Rust, vei întâlni o eroare de compilare. Prin urmare, Rust nu are noțiunea de colectare a gunoiului.

fn main() {
      let num:i32;
      println!("Valoarea lui num este: {}",num);
  }
eroare[E0381]: legătura `num` folosită nu este inițializată
   --> src/main.rs:3:40
    |
  2 |     let num:i32;
    |         --- legătură declarată aici, dar lăsată neinițializată
  3 |     println!("Valoarea lui num este: {}",num);
    |                                          ^^^ `num` folosită aici, dar nu este inițializată
    |

Siguranța memoriei la momentul compilării

Rust asigură siguranța memoriei în timpul compilării. Să luăm un exemplu simplu. Aici, deși instrucțiunea condițională if are valoarea booleană true, ceea ce ar însemna că valoarea lui num va fi întotdeauna 100, obținem o eroare când încercăm să afișăm valoarea lui num.

fn main() {
      let num:i32;
      if true{
          num = 100;
      }
      println!("Valoarea lui num este: {}", num);
  }

Acest lucru se întâmplă deoarece evaluarea condiției se face în timpul execuției, iar compilatorul nu poate garanta că num are o valoare în timpul compilării.

eroare[E0381]: legătura `num` folosită este posibil neinițializată
   --> src/main.rs:6:41
    |
  2 |     let num:i32;
    |         --- legătură declarată aici, dar lăsată neinițializată
  3 |     if true{
    |        ---- dacă această condiție `if` este `false`, `num` nu este inițializată
  4 |         num = 100;
  5 |     }
    |      - o ramură `else` ar putea lipsi aici, inițializând `num`
  6 |     println!("Valoarea lui num este: {}", num);
    |                                          ^^^ `num` folosită aici, dar este posibil neinițializată

Dacă analizezi mai atent mesajul de eroare, vei observa că printr-o instrucțiune else, ne putem asigura că num va avea o valoare. Așadar, următorul cod se va executa fără erori. Deoarece în acest fel, compilatorul poate determina că num va avea o valoare – la momentul compilării – astfel încât nu mai există erori.

fn main() {
      let num:i32;
      if true{
          num = 100;
      }
      else{
          num = 50;
      }
      println!("Valoarea lui num este: {}", num);
  }
Valoarea lui num este: 100

Imuabilitatea variabilelor

Este util de reținut că variabilele în Rust sunt imuabile în mod implicit. Acest lucru înseamnă că tu, ca dezvoltator, nu trebuie să îți faci griji cu privire la suprascrierea accidentală a valorii unei anumite variabile. Iată un exemplu:

fn main() {
      let num1 = 10;
      num1 = 5;
      println!("Valoarea lui num1 este: {}", num1);
  }

Deoarece num1 este inițializată la 10, când încerci să-i atribui o valoare de 5, primești un mesaj de eroare care spune „nu se poate atribui de două ori variabilei imuabile num1”.

eroare[E0384]: nu se poate atribui de două ori variabilei imuabile `num1`
   --> src/main.rs:3:5
    |
  2 |     let num1 = 10;
    |         ----
    |         |
    |         prima atribuire pentru `num1`
    |         ajutor: ia în considerare transformarea acestei legături într-una mutabilă: `mut num1`
  3 |     num1 = 5;
    |     ^^^^^^^^ nu se poate atribui de două ori variabilei imuabile

Proprietatea și împrumutul

Proprietatea asigură siguranța memoriei. Din punct de vedere funcțional, proprietatea în Rust poate fi rezumată astfel:

Fiecare obiect ar trebui să aibă un singur proprietar. Dacă proprietarul iese din domeniu, atunci obiectul este eliberat.

Să luăm un exemplu simplu. Aici, inițializăm un șir str1, apoi îi mutăm valoarea în str2. Deoarece fiecare obiect poate avea un singur proprietar, obiectul str1 este abandonat imediat ce valoarea sa este mutată în str2.

fn main() {
      let str1 = String::from("Rust");
      let str2 = str1;
      println!("Valoarea lui str1 este: {}", str1);
  }
eroare[E0382]: împrumutul valorii mutate: `str1`
   --> src/main.rs:4:42
    |
  2 |     let str1 = String::from("Rust");
    |         ---- mutarea are loc deoarece `str1` are tipul `String`, care nu implementează trăsătura `Copy`
  3 |     let str2 = str1;
    |                ---- valoarea a fost mutată aici
  4 |     println!("Valoarea lui str1 este: {}", str1);
    |                                            ^^^^ valoarea împrumutată aici după mutare

Deși acest lucru pare intuitiv, pentru a înțelege și a aprecia mai bine cum funcționează proprietatea, este util să te familiarizezi cu conceptele de împrumut și referințe.

Dezvoltare rapidă

Până acum, am discutat câteva caracteristici utile ale limbajului de programare Rust. Pentru a recapitula, menționăm:

  • Rust este optimizat atât pentru viteză, cât și pentru siguranță.
  • Vine cu un instrument integrat de gestionare a pachetelor și un sistem de construire.
  • Are, de asemenea, o bibliotecă standard extinsă.

În esență, Rust oferă tot ceea ce un dezvoltator poate solicita. Prin urmare, cu Rust, poți dezvolta rapid aplicații cu depanare minimă și lansări mai rapide.

Dezvoltare multi-platformă

Cu Rust, poți alege să dezvolți pe platforma dorită. Rust suportă cele mai utilizate platforme: Linux, MacOS și Windows.

Dezvoltarea unei aplicații este în general ușoară, deoarece poți compila codul sursă Rust într-un executabil, fără a depinde de alte instrumente de compilare sau compilatoare externe.

O comunitate activă are un rol important în simplificarea procesului de învățare. Rust are o bază mare de utilizatori, care crește în fiecare an.

Popularitatea lui Rust în sondajul StackOverflow pentru dezvoltatori indică existența unei comunități mari de utilizatori, cu mulți dezvoltatori experimentați dispuși să-și împărtășească cunoștințele și expertiza.

Pe lângă documentația oficială, există și un site de documentație creat de utilizatori, precum și un forum de discuții. De asemenea, poți consulta grupurile Rust de pe subreddit și LinkedIn pentru discuții relevante.

Resurse de învățare pentru a începe cu Rust

Această secțiune oferă o listă cu câteva resurse utile care te pot ajuta să începi cu Rust. Aceasta nu este o listă exhaustivă, dar include câteva tutoriale, cursuri și cărți recomandate pentru a te sprijini în procesul de învățare.

#1. Rust Prin Exemple

Rust By Example te va învăța elementele de bază ale limbajului Rust și ale bibliotecilor standard prin intermediul unei serii de exemple, pe care le poți executa într-un editor online.

Printre subiectele acoperite se numără depozitele de cod, Cargo, instrumentul de gestionare a pachetelor pentru Rust, generice, trăsături, gestionarea erorilor și multe altele.

#2. Rustlings

Rustlings este o altă resursă oficială de învățare a limbajului de programare Rust. Este similară cu Rust By Example. Cu toate acestea, trebuie să configurezi mediul local de dezvoltare, să clonezi un exemplu de depozit și să rezolvi probleme simple pentru a învăța aceste concepte.

#3. Exercitii pe Rust Track

Rust Track de pe Exercism oferă peste 100 de exerciții, care te vor ajuta să înveți și să testezi înțelegerea limbajului Rust. Exercism este o platformă gratuită, unde poți primi îndrumare de la programatori experimentați, pe lângă scrierea codului pentru exerciții.

#4. Cursul accelerat Ultimate Rust

Cursul accelerat Ultimate Rust, predat de Nathan Stocks pe Udemy, acoperă următoarele:

  • Fundamentele programării în Rust
  • Sistemul de module în Rust
  • Tipuri de date și flux de control
  • Referințe și împrumuturi
  • Structuri, trăsături și colecții

#5. Ultimate Rust 2: Concepte intermediare

Ultimate Rust 2 este un curs care continuă cursul accelerat Ultimate Rust și acoperă următoarele subiecte:

  • Închideri
  • Iteratori
  • Gestionarea erorilor
  • Teste unitare și de integrare
  • Logare, multi-threading și canale

#6. Rust lang: Ghidul complet pentru începători 2023

Acest curs Udemy, predat de Catalin Stefan, este un curs complet despre programarea în Rust. Printre subiectele abordate se numără:

  • Bazele limbajului Rust
  • Tipuri de date, structuri de control
  • Funcții, trăsături
  • Gestionarea memoriei
  • Concurență

#7. Programare în Rust: Dezvoltare rapidă și sigură a sistemelor

Programare în Rust de O’Reilly este o carte populară despre programarea în Rust, care te va învăța următoarele:

  • Tipuri fundamentale de date
  • Proprietatea și împrumutul
  • Programare asincronă
  • Aplicații rapide multi-threading
  • Închideri, iteratoare
  • Colecții

#8. Limbajul de programare Rust, ediția a 2-a

Limbajul de programare Rust este creat de colaboratori de renume din comunitatea Rust. Această carte acoperă tot ce trebuie să știi despre Rust, inclusiv:

  • Proprietatea și împrumutul
  • Generice, trăsături
  • Indicatori inteligenți, multi-threading
  • Testarea și gestionarea erorilor

#9. Ghidul complet de referință pentru programarea în Rust

Ghidul complet de referință pentru programarea în Rust de la Packt acoperă următoarele:

  • Implementarea structurilor de date în Rust
  • Scrierea componentelor reutilizabile și testabile în Rust
  • Conceperea de aplicații multi-threaded, conceperea algoritmilor și
  • Aplicațiile Rust în WebAssembly, rețele și aplicații de linie de comandă

#10. Proiecte creative pentru programatorii Rust

Dacă ești un dezvoltator experimentat care învață Rust, atunci construirea unor proiecte în domeniul tău de interes va fi suficientă pentru a înțelege bine limbajul. Proiecte creative pentru programatorii Rust de la Packt este o carte care te învață Rust aplicând cunoștințele la proiecte precum:

  • Crearea de servicii web RESTful
  • Jocuri 2D cu
  • Dezvoltarea de aplicații web folosind WebAssembly
  • Emulatoare de limbaj mașină
  • și multe altele!

Concluzie

Acest articol a oferit o prezentare generală a Rust ca limbaj de programare a sistemelor, inclusiv caracteristici precum siguranța memoriei, gestionarea îmbunătățită a pachetelor și multe altele. De asemenea, am enumerat resurse de învățare care te vor ajuta să începi să folosești Rust.

În continuare, poți alege una sau mai multe dintre resursele de învățare menționate pentru a afla elementele de bază ale Rust. Îți urăm succes în programarea cu Rust!

De asemenea, poți explora câțiva dintre cei mai buni furnizori de găzduire pentru servere Rust.