Ruggine - Tipi generici

I generici sono una struttura per scrivere codice per più contesti con tipi diversi. In Rust, i generici si riferiscono alla parametrizzazione dei tipi di dati e delle caratteristiche. Generics consente di scrivere codice più conciso e pulito riducendo la duplicazione del codice e fornendo l'indipendenza dai tipi. Il concetto di Generics può essere applicato a metodi, funzioni, strutture, enumerazioni, raccolte e tratti.

Il <T> syntaxnoto come parametro di tipo, viene utilizzato per dichiarare un costrutto generico. T rappresenta qualsiasi tipo di dati.

Illustrazione: raccolta generica

L'esempio seguente dichiara un vettore che può memorizzare solo numeri interi.

fn main(){
   let mut vector_integer: Vec<i32> = vec![20,30];
   vector_integer.push(40);
   println!("{:?}",vector_integer);
}

Produzione

[20, 30, 40]

Considera il seguente frammento:

fn main() {
   let mut vector_integer: Vec<i32> = vec![20,30];
   vector_integer.push(40);
   vector_integer.push("hello"); 
   //error[E0308]: mismatched types
   println!("{:?}",vector_integer);
}

L'esempio sopra mostra che un vettore di tipo intero può memorizzare solo valori interi. Quindi, se proviamo a inserire un valore di stringa nella raccolta, il compilatore restituirà un errore. I generici rendono le raccolte più sicure per i tipi.

Illustrazione: struttura generica

Il parametro type rappresenta un tipo, che il compilatore compilerà in seguito.

struct Data<T> {
   value:T,
}
fn main() {
   //generic type of i32
   let t:Data<i32> = Data{value:350};
   println!("value is :{} ",t.value);
   //generic type of String
   let t2:Data<String> = Data{value:"Tom".to_string()};
   println!("value is :{} ",t2.value);
}

L'esempio precedente dichiara una struttura generica denominata Data . Il tipo <T> indica un tipo di dati. La funzione main () crea due istanze: un'istanza intera e un'istanza stringa della struttura.

Produzione

value is :350
value is :Tom

Tratti

I tratti possono essere utilizzati per implementare un insieme standard di comportamenti (metodi) su più strutture. I tratti sono comeinterfacesnella programmazione orientata agli oggetti. La sintassi del tratto è come mostrato di seguito:

Dichiara un tratto

trait some_trait {
   //abstract or method which is empty
   fn method1(&self);
   // this is already implemented , this is free
   fn method2(&self){
      //some contents of method2
   }
}

I tratti possono contenere metodi concreti (metodi con corpo) o metodi astratti (metodi senza corpo). Utilizzare un metodo concreto se la definizione del metodo sarà condivisa da tutte le strutture che implementano il tratto. Tuttavia, una struttura può scegliere di sovrascrivere una funzione definita dal tratto.

Utilizzare metodi astratti se la definizione del metodo varia per le strutture di implementazione.

Sintassi: implementa un tratto

impl some_trait for structure_name {
   // implement method1() there..
   fn method1(&self ){
   }
}

I seguenti esempi definiscono un tratto stampabile con un metodo print () , che è implementato dal libro di struttura .

fn main(){
   //create an instance of the structure
   let b1 = Book {
      id:1001,
      name:"Rust in Action"
   };
   b1.print();
}
//declare a structure
struct Book {
   name:&'static str,
   id:u32
}
//declare a trait
trait Printable {
   fn print(&self);
}
//implement the trait
impl Printable for Book {
   fn print(&self){
      println!("Printing book with id:{} and name {}",self.id,self.name)
   }
}

Produzione

Printing book with id:1001 and name Rust in Action

Funzioni generiche

L'esempio definisce una funzione generica che visualizza un parametro ad essa passato. Il parametro può essere di qualsiasi tipo. Il tipo del parametro dovrebbe implementare il tratto Display in modo che il suo valore possa essere stampato da println! macro.

use std::fmt::Display;

fn main(){
   print_pro(10 as u8);
   print_pro(20 as u16);
   print_pro("Hello TutorialsPoint");
}

fn print_pro<T:Display>(t:T){
   println!("Inside print_pro generic function:");
   println!("{}",t);
}

Produzione

Inside print_pro generic function:
10
Inside print_pro generic function:
20
Inside print_pro generic function:
Hello TutorialsPoint