Salt la conținutul principal
Modulul 5 · Lecția 1 din 29/14 în curs~12 min
Lecții din modul (1/2)

Generice și funcții

Generice vă permit să scrieți cod flexibil, reutilizabil, evitând duplicarea logicii pentru diferite tipuri de date. În loc să definim mai multe funcții sau structuri pentru diferite tipuri (cum ar fi i32, f64 sau String), putem folosi un parametru de tip generic, reprezentat în mod convențional prin litera T.

Compilatorul Rust gestionează generice folosind un proces numit monomorfizare: în timpul compilării, generează o copie a codului generic pentru fiecare tip de beton care este efectiv utilizat. Aceasta înseamnă că nu există nicio suprasarcină de performanță la timpul de rulare.


Funcții generice

Pentru a defini o funcție generică, inserăm parametrul de tip <T> imediat după numele funcției și înaintea listei de argumente:

Rust
fn print_value<T: std::fmt::Debug>(value: T) {
    println!("Value: {:?}", value);
}

În funcțiile generice, putem folosi tipul generic T atât pentru tipurile de argument, cât și pentru tipurile de returnare:

Rust
fn identity<T>(value: T) -> T {
    value
}

Structuri generice

De asemenea, putem folosi parametrii de tip generic în interiorul structurilor (struct) pentru a defini câmpuri flexibile:

Rust
struct KeyValuePair<K, V> {
    key: K,
    value: V,
}

fn main() {
    let pair = KeyValuePair {
        key: String::from("age"),
        value: 30,
    };
}

Într-un bloc impl pentru o structură generică, trebuie să declarăm parametrul de tip <T> imediat după cuvântul cheie impl pentru a indica că implementăm metode pe o structură generică:

Rust
struct Container<T> {
    value: T,
}

impl<T> Container<T> {
    fn new(value: T) -> Self {
        Container { value }
    }

    fn value(&self) -> &T {
        &self.value
    }
}

Încercați-l singur

Exercițiul 1: Structura punctuală

Exercițiu#rust.m5.l1.e1
Încercări: 0Se încarcă…

Definiți o structură generică numită Point<T> cu două câmpuri: x de tip T și y de tip T. În funcția principală, instanțiați un punct variabil care conține un Punct cu valori întregi x = 5 și y = 10, apoi tipăriți valoarea punct.x.

Se încarcă editorul...
Afișează indiciu

Declarați structura folosind `struct Point<T> { x: T, y: T }`. Instanțiază-l în principal și folosește `point.x` pentru a-l imprima.

Soluție disponibilă după 3 încercări

Exercițiul 2: Inversarea unui tuplu cu swap

Exercițiu#rust.m5.l1.e2
Încercări: 0Se încarcă…

Scrieți o funcție generică numită swap<T> care acceptă un tuplu de două elemente (T, T) și returnează un nou tuplu (T, T) cu pozițiile lor inversate. În funcția principală, apelați funcția cu tuplu (1, 2) și imprimați rezultatul.

Se încarcă editorul...
Afișează indiciu

Semnătura funcției trebuie să fie `fn swap<T>(pereche: (T, T)) -> (T, T)`. Returnează tuplu inversat cu `(pair.1, pair.0)`.

Soluție disponibilă după 3 încercări

Exercițiul 3: Structura containerului

Exercițiu#rust.m5.l1.e3
Încercări: 0Se încarcă…

Definiți o structură generică Container<T> care conține un câmp de valoare de tip T. Implementați un bloc generic impl pentru a defini o nouă metodă care acceptă o valoare de tip T și returnează o instanță a Container<T>.

Se încarcă editorul...
Afișează indiciu

Folosiți `impl<T> Container<T>` pentru a implementa metoda asociată`fn new(valoare: T) -> Self { Container { value } }`.

Soluție disponibilă după 3 încercări