Óxido - Tipos genéricos

Los genéricos son una facilidad para escribir código para múltiples contextos con diferentes tipos. En Rust, los genéricos se refieren a la parametrización de tipos de datos y rasgos. Generics permite escribir código más conciso y limpio al reducir la duplicación de código y proporcionar seguridad de tipos. El concepto de Genéricos se puede aplicar a métodos, funciones, estructuras, enumeraciones, colecciones y rasgos.

los <T> syntaxconocido como parámetro de tipo, se utiliza para declarar una construcción genérica. T representa cualquier tipo de datos.

Ilustración: Colección Genérica

El siguiente ejemplo declara un vector que solo puede almacenar enteros.

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

Salida

[20, 30, 40]

Considere el siguiente fragmento:

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);
}

El ejemplo anterior muestra que un vector de tipo entero solo puede almacenar valores enteros. Entonces, si intentamos insertar un valor de cadena en la colección, el compilador devolverá un error. Los genéricos hacen que las colecciones sean más seguras para los tipos.

Ilustración: Estructura genérica

El parámetro de tipo representa un tipo, que el compilador completará más adelante.

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);
}

El ejemplo anterior declara una estructura genérica denominada Data . El tipo <T> indica algún tipo de datos. La función main () crea dos instancias: una instancia entera y una instancia de cadena, de la estructura.

Salida

value is :350
value is :Tom

Rasgos

Los rasgos se pueden utilizar para implementar un conjunto estándar de comportamientos (métodos) en múltiples estructuras. Los rasgos son comointerfacesen Programación Orientada a Objetos. La sintaxis del rasgo es la que se muestra a continuación:

Declarar un rasgo

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
   }
}

Los rasgos pueden contener métodos concretos (métodos con cuerpo) o métodos abstractos (métodos sin cuerpo). Utilice un método concreto si la definición del método será compartida por todas las estructuras que implementan el Rasgo. Sin embargo, una estructura puede optar por anular una función definida por el rasgo.

Utilice métodos abstractos si la definición del método varía para las estructuras de implementación.

Sintaxis: implementar un rasgo

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

Los siguientes ejemplos definen un rasgo Printable con un método print () , que es implementado por el libro de estructura .

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)
   }
}

Salida

Printing book with id:1001 and name Rust in Action

Funciones genéricas

El ejemplo define una función genérica que muestra un parámetro que se le pasa. El parámetro puede ser de cualquier tipo. El tipo de parámetro debe implementar el rasgo Display para que su valor pueda ser impreso por 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);
}

Salida

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