Software în Rust folosind Visual Studio Code (VS Code)
VS code este un editor popular care are suport pentru o varietate de limbaje de programare, inclusiv Rust. Pentru a începe să dezvolți în Rust cu VS Code, va trebui să urmezi câțiva pași:
Instalarea Rust: Mai întâi, trebuie să instalezi Rust pe sistemul tău. Poți face acest lucru folosind instrumentul "rustup":
- Pe Linux sau macOS, deschide terminalul și execută comanda
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
. - Pe Windows, descarcă și rulează instalatorul de pe site-ul oficial al Rust: https://www.rust-lang.org/tools/install.
- Pe Linux sau macOS, deschide terminalul și execută comanda
Instalarea Visual Studio Code: Dacă nu ai deja VS Code, poți să-l descarci și să-l instalezi de pe site-ul său oficial: https://code.visualstudio.com/.
Extensii Rust pentru VS Code:
- Deschide VS Code și accesează secțiunea de extensii (de obicei, simbolizată printr-un mic pătrat în partea stângă).
- Caută extensia "rust-analyzer" și instaleaz-o. Această extensie oferă suport pentru dezvoltarea în Rust, inclusiv completarea automată a codului, evidențierea sintaxei, și alte caracteristici utile.
- Poți instala și alte extensii utile, cum ar fi "CodeLLDB" pentru depanare (debugging) în Rust.
Crearea unui nou proiect Rust:
- În terminal, poți crea un nou proiect Rust folosind comanda
cargo new nume_proiect
. - Deschide proiectul în VS Code și începe să scrii cod Rust.
- În terminal, poți crea un nou proiect Rust folosind comanda
Rularea și Depanarea:
- Pentru a rula codul tău Rust, poți folosi
cargo run
în terminalul din VS Code. - Pentru depanare, poți folosi extensia "CodeLLDB" sau alte instrumente de depanare compatibile cu Rust.
Configurarea Proiectului pentru Depanare
- După ce ai instalat
CodeLLDB
, va trebui să configurezi Visual Studio Code pentru depanare. - Asigură-te că ai un proiect Rust creat cu
cargo
(de exemplu,cargo new nume_proiect
). - În directorul proiectului, creează un fișier de configurare pentru depanare:
- Accesează secțiunea "Run and Debug" în VS Code.
- Apasă butonul "create a launch.json file" pentru a crea un fișier de configurare.
- Alege opțiunea "C++ (GDB/LLDB)" pentru a genera un șablon.
Configurarea
launch.json
pentru Depanare- Pentru a rula codul tău Rust, poți folosi
- În fișierul
launch.json
, poți configura parametrii pentru depanare. Iată un exemplu de configurare pentru depanarea unui program Rust:
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Launch Rust Program",
"program": "${workspaceFolder}/target/debug/nume_proiect", // Calea către executabil
"args": [], // Argumente suplimentare pentru programul tău
"cwd": "${workspaceFolder}", // Directorul de lucru
"stopOnEntry": false, // Dacă vrei să oprești la început
"showDisassembly": "never"
}
]
}
program
: Calea către executabilul Rust (de obicei în directorultarget/debug/
).args
: Argumente suplimentare pentru program.cwd
: Directorul de lucru pentru depanare.stopOnEntry
: Dacă ar trebui să oprești la începutul programului.showDisassembly
: Configurația pentru vizualizarea codului de asamblare (poți setanever
,always
, sauauto
).
Rularea și Depanarea Programului
- Odată ce ai configurat fișierul
launch.json
, poți începe să depanezi: - Plasează un breakpoint în cod (făcând clic în bara laterală din stânga, lângă linia de cod).
- Accesează secțiunea "Run and Debug" și selectează configurația "Launch Rust Program".
- Apasă pe butonul de pornire pentru a începe depanarea.
- Codul tău va rula până la primul breakpoint sau până când se termină. Dacă ai breakpoint-uri, poți inspecta variabilele, vizualiza stiva de apeluri, și folosi alte unelte de debugging.
- În timpul depanării, poți folosi următoarele funcții:
- Breakpoint-uri: Plasează breakpoint-uri pentru a opri execuția în anumite puncte.
- Pas peste: Execută codul linie cu linie fără a intra în funcții.
- Pas înăuntru: Intră în funcții pentru a vedea execuția detaliată.
- Pas în afară: Iese din funcția curentă și revine la apelant.
- Inspecția variabilelor: Vizualizează valorile variabilelor și a altor structuri de date.
- Stiva de apeluri: Vezi secvența de apeluri a funcțiilor pentru a înțelege contextul execuției.
- Evaluare expresii: Evaluază expresii Rust pentru a verifica valori sau pentru a schimba variabile în timpul depanării
Fișiere care conțin cod Rust
Un fișier care conține cod Rust are extensia .rs
.
Aceste fișiere sunt folosite pentru a defini module, funcții, structuri, enumerații și alte elemente ale codului Rust. De exemplu:
- Un fișier numit
main.rs
ar putea conține punctul de intrare al unei aplicații Rust. - Un fișier numit
lib.rs
este de obicei punctul de intrare pentru o bibliotecă Rust. - Alte fișiere cu extensia
.rs
pot conține module sau alte componente ale unui proiect Rust.
Sintaxa de bază a limbajului Rust
Rust este un limbaj de programare conceput pentru a oferi siguranță, performanță și control asupra memoriei, fără a sacrifica eficiența. Este cunoscut pentru sistemul său de proprietate (ownership), care ajută la evitarea erorilor legate de memorie, cum ar fi cele de dangling pointers sau race conditions.
Să vedem câteva aspecte fundamentale ale sintaxei Rust:
Structura de bază a unui program Rust
Un program Rust este compus, de obicei, din module și funcții. Iată un exemplu simplu de program Rust:
fn main() {
println!("Hello world!");
}
fn
definește o funcție.main
este punctul de intrare al unui program Rust.println!
este un macro care imprimă text în consolă.
Variabile și Tipuri de Date
Variabilele sunt de obicei imutabile în Rust, dar pot fi făcute mutable cu cuvântul cheie mut
.
fn main() {
let numar = 10; // Variabilă imutabilă
let mut alt_numar = 20; // Variabilă mutabilă
}
Rust are tipuri de date primare, cum ar fi:
- Numerice:
i32
,u32
,f32
, etc. - Boolean:
bool
(valoritrue
saufalse
). - Caractere:
char
. - Strings:
String
sau&str
.
Structuri de Control
Rust are structuri de control standard, precum if-else
, match
, și bucle (loop
, for
, while
).
fn main() {
let numar = 10;
if numar > 5 {
println!("Numărul este mai mare decât 5.");
} else {
println!("Numărul este 5 sau mai mic.");
}
// Folosind `for` pentru a itera peste un interval de valori
for i in 1..=5 {
println!("{}", i);
}
}
Funcții și Returnuri
Funcțiile pot primi argumente și pot returna valori.
fn aduna(x: i32, y: i32) -> i32 {
x + y // Ultima expresie este valoarea returnată
}
fn main() {
let suma = aduna(5, 7);
println!("Suma este {}", suma);
}
- Tipul de return este indicat cu
->
. - Returnarea implicită este ultima expresie din funcție (fără punct și virgulă).
Structuri și Enumerații
Rust permite definirea de structuri (structs
) și enumerații (enums
).
// Definirea unei structuri
struct Persoana {
nume: String,
varsta: u32,
}
fn main() {
let persoana = Persoana {
nume: "Ion".to_string(),
varsta: 30,
};
println!("Nume: {}, Vârstă: {}", persoana.nume, persoana.varsta);
}
Enumerații
// Definirea unei enumerații
enum Zi {
Luni,
Marti,
Miercuri,
}
fn main() {
let zi = Zi::Marti;
match zi {
Zi::Luni => println!("Este luni"),
Zi::Marti => println!("Este marți"),
_ => println!("Este o altă zi"),
}
}
Ownership și Borrowing
Sistemul de ownership și borrowing este unic în Rust și este esențial pentru siguranța memoriei.
- Ownership: Fiecare valoare din Rust are un proprietar. Când proprietatea este transferată (prin mutare), nu poate fi utilizată de vechiul proprietar.
- Borrowing: Poți împrumuta (borrow) referințe către valori fără a le transfera proprietatea.
fn main() {
let mut mesaj = String::from("Salut");
saluta(&mesaj); // Împrumutăm o referință la mesaj
adauga_exclamatie(&mut mesaj); // Împrumutăm o referință mutabilă
println!("{}", mesaj);
}
fn saluta(text: &str) {
println!("{}", text); // Folosim referința
}
fn adauga_exclamatie(text: &mut String) {
text.push_str("!"); // Modificăm valoarea împrumutată
}
Programarea orientă pe obiecte în Rust
Rust suportă conceptul de programare orientată pe obiecte (OOP), dar are o abordare diferită față de alte limbaje precum C++ sau Java. În Rust, programarea orientată pe obiecte se concentrează pe câteva concepte cheie:
Structuri (Structs): Structurile în Rust sunt asemănătoare claselor în alte limbaje. Ele pot conține variabile (denumite "field-uri") și metode. Spre deosebire de alte limbaje, Rust nu are mecanismul de moștenire a claselor. Cu toate acestea, poți avea metode asociate structurilor și poți implementa trăsături (traits), oferind astfel funcționalități similare cu OOP.
struct Persoana {
nume: String,
varsta: u32,
}
impl Persoana {
fn descrie(&self) -> String {
format!("{} are {} ani.", self.nume, self.varsta)
}
}
fn main() {
let persoana = Persoana {
nume: String::from("Ion"),
varsta: 30,
};
println!("{}", persoana.descrie());
}
impl
este utilizat pentru a implementa metode pentru structuri.- Metodele pot lua referințe la instanța structurii (
&self
).
Trăsături (Traits): Trăsăturile sunt similare cu interfețele din alte limbaje. Ele definesc un set de metode pe care structurile trebuie să le implementeze pentru a fi conforme cu acea trăsătură. Trăsăturile permit polimorfismul în Rust.
trait Salut {
fn saluta(&self);
}
struct Persoana {
nume: String,
}
impl Salut pentru Persoana {
fn saluta(&self) {
println!("Salut, eu sunt {}.", self.nume);
}
}
fn main() {
let persoana = Persoana { nume: String::from("Ana") };
persoana.saluta();
}
- Trăsăturile permit definirea de metode pe care structurile le pot implementa.
- Trăsăturile pot fi utilizate pentru polimorfism, permițând manipularea structurilor care implementează aceeași trăsătură într-un mod generic.
Encapsularea:
Rust oferă control asupra vizibilității prin cuvinte cheie precum pub
. Variabilele și metodele din structuri sunt private în mod implicit, dar pot fi făcute publice cu pub
.
struct Persoana {
pub nume: String, // Public
varsta: u32, // Privat
}
impl Persoana {
pub fn seteaza_varsta(&mut self, varsta: u32) {
self.varsta = varsta;
}
}
pub
face un field sau o metodă publică.- Controlul vizibilității este important pentru encapsularea datelor.
Chiar dacă Rust nu are moștenire clasică de la clasă la clasă, combinarea acestor concepte permite dezvoltarea în stil OOP cu funcționalități de tip polimorfism și encapsulare. Rust se concentrează pe siguranța memoriei, astfel încât aceste mecanisme sunt concepute pentru a minimiza riscul de erori legate de memorie.
Sisteme Embedded
Rust este potrivit pentru dezvoltarea de sisteme embedded. Rust oferă siguranța memoriei și controlul precis asupra resurselor, ceea ce îl face atractiv pentru dezvoltarea de software în medii embedded unde performanța și fiabilitatea sunt critice.
Iată câteva motive pentru care Rust este o alegere bună pentru dezvoltarea de sisteme embedded:
Siguranța Memoriei
- Rust previne multe erori legate de memorie, cum ar fi dangling pointers, buffer overflows, și race conditions. Acest lucru este crucial în sistemele embedded, unde erorile de memorie pot fi deosebit de problematice.
Performanță
- Rust este un limbaj compilat care oferă performanță comparabilă cu limbaje precum C sau C++. Acest lucru îl face potrivit pentru sisteme embedded, unde eficiența și consumul redus de resurse sunt importante.
Control asupra Resurselor
- Rust permite un control detaliat asupra gestionării resurselor și a interacțiunii cu hardware-ul, ceea ce este esențial în dezvoltarea de sisteme embedded.
Suport pentru Platforme Embedded
- Rust are un ecosistem în creștere pentru dezvoltarea de sisteme embedded. Există diverse crate-uri (biblioteci Rust) și unelte care permit dezvoltarea pe platforme embedded, cum ar fi microcontrolere și dispozitive IoT. Câteva resurse utile includ:
- Cortex-M și alte microcontrolere ARM: Rust oferă suport pentru microcontrolere Cortex-M și alte platforme ARM. Există crate-uri precum
cortex-m
șicortex-m-rt
care ajută la dezvoltarea pentru aceste microcontrolere. - RISCV: Rust are suport pentru platforme RISCV, o arhitectură deschisă populară în lumea embedded.
- RTIC (Real-Time Interrupt-driven Concurrency): RTIC este un framework pentru dezvoltarea de aplicații embedded cu multitasking și evenimente în timp real.
- No_std: Rust poate fi folosit fără biblioteca standard (
no_std
), permițând dezvoltarea pe platforme cu resurse limitate. Comunitate și Documentație
- Comunitatea Rust pentru dezvoltarea embedded este activă și oferă resurse și documentație pentru a începe. Proiectul Embedded Rust este un bun punct de pornire.
Interacțiunea cu Hardware-ul
- Rust permite interacțiuni directe cu hardware-ul, inclusiv accesul la registre și manipularea directă a acestora. Acest lucru îl face potrivit pentru controlul hardware-ului în sistemele embedded.
În concluzie, Rust este o alegere viabilă pentru dezvoltarea de sisteme embedded datorită siguranței memoriei, performanței și controlului oferit asupra resurselor. Cu suportul pentru platforme embedded și ecosistemul în creștere, Rust devine din ce în ce mai popular în această zonă. Dacă ai întrebări specifice sau dorești să explorezi resurse pentru dezvoltarea embedded în Rust, sunt aici pentru a te ajuta.
Documentație
- Limbajul rust
- Programming Rust: Fast, Safe Systems Development - Jim Blandy
- https://www.rust-lang.org/
- https://doc.rust-lang.org/rust-by-example/
- https://github.com/SimedruF/Simple_Rust_Test
Enjoy Rust !
Afiliere eMag
Linkurile de la secțiunea "Documentație" conțin adresa mea de afiliere la eMag.ro, iar dacă cumperi folosind aceste linkuri vei susține blogul meu, iar 10% din donații se vor direcționa pentru fundația dăruiește viată. Mulțumesc !Mulțumesc pentru atenție!
Pentru întrebări și/sau consultanță tehnică vă stau la dispoziție pe blog mai jos în secțiunea de comentarii sau pe email simedruflorin@automatic-house.ro.O zi plăcută tuturor !
Back to top of page