Ferrugem - Tipos Genéricos

Os genéricos são uma facilidade para escrever código para vários contextos com diferentes tipos. No Rust, os genéricos referem-se à parametrização de tipos de dados e características. Genéricos permitem escrever código mais conciso e limpo, reduzindo a duplicação de código e fornecendo segurança de tipo. O conceito de Genéricos pode ser aplicado a métodos, funções, estruturas, enumerações, coleções e características.

o <T> syntaxconhecido como parâmetro de tipo, é usado para declarar uma construção genérica. T representa qualquer tipo de dados.

Ilustração: coleção genérica

O exemplo a seguir declara um vetor que pode armazenar apenas inteiros.

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

Resultado

[20, 30, 40]

Considere o seguinte snippet -

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

O exemplo acima mostra que um vetor do tipo inteiro só pode armazenar valores inteiros. Portanto, se tentarmos inserir um valor de string na coleção, o compilador retornará um erro. Os genéricos tornam as coleções mais seguras.

Ilustração: Estrutura Genérica

O parâmetro type representa um tipo, que o compilador preencherá mais tarde.

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

O exemplo acima declara uma estrutura genérica chamada Data . O tipo <T> indica algum tipo de dado. A função main () cria duas instâncias - uma instância de inteiro e uma instância de string da estrutura.

Resultado

value is :350
value is :Tom

Traços

As características podem ser usadas para implementar um conjunto padrão de comportamentos (métodos) em várias estruturas. Traços são comointerfacesem Programação Orientada a Objetos. A sintaxe do trait é mostrada abaixo -

Declare uma característica

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

As características podem conter métodos concretos (métodos com corpo) ou métodos abstratos (métodos sem corpo). Use um método concreto se a definição do método for compartilhada por todas as estruturas que implementam a Característica. No entanto, uma estrutura pode optar por substituir uma função definida pelo traço.

Use métodos abstratos se a definição do método variar para as estruturas de implementação.

Sintaxe - Implementar um Traço

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

Os exemplos a seguir definem uma característica Printable com um método print () , que é implementado pelo livro de estrutura .

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

Resultado

Printing book with id:1001 and name Rust in Action

Funções Genéricas

O exemplo define uma função genérica que exibe um parâmetro passado a ela. O parâmetro pode ser de qualquer tipo. O tipo do parâmetro deve implementar o traço Display para que seu valor possa ser impresso pelo 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);
}

Resultado

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