Algoritmos y Estructuras de Datos Herramientas Lenguaje de programación
!Prog C/C++ Rust
Linux Matemáticas
Mates Discretas
Programación Orientada a Objetos Sistemas Operativos

Generics, traits y closures


[words: 375] [reading time: 2min] [size: 20823 bytes]

Generics

Usa varios tipos de datos en uno solo.

 1fn foo<T>(a: T, b: T)    { ... }
 2fn foo<T, U>(a: T, b: U) { ... }
 3
 4// podemos especificar q tipo de dato es y no cualquiera con traits
 5fn foo<T: PartialOrd + Copy>(a: T) // `a` se puede comparar y copiar
 6
 7// tambien aplicable a structs y enums
 8impl<T> foo<T> { ... }
 9// no depende de la definicion en el struct incluso podemos crear impl foo<char>
10// todo esto no afecta al rendimiento

Traits

Sirven de plantillas para crear otras estructuras.

 1trait trait_example {
 2  fn foo(); // podemos añadir una definición por defecto (se sobreescribe despues)
 3}
 4
 5struct struct_example { ... }
 6
 7impl trait_example for struct_example {
 8  fn foo(){
 9    // algo
10  }
11}

Podemos pasar traits como parámetros, de esta forma, funcionan como un generic algo más restringido:

1fn foo(a: &(impl trait_example + other_trait)) -> impl name { ... }

Hablando de generics, podemos usar esta otra sintaxis (trait bounds):

1fn foo<T: trait_example + other_trait>(a: T, b: T) { ... }
2fn foo<T, U> (a: T, b: U) -> char where T: trait_example, U: trait_example + other_trait { ... }

Closures

Son funciones sin nombre que pueden guardarse, usarse como si fuesen datos, pasarlas como parámetros, etc.

1let closure = |params| { ... } // si es una línea se puede borrar las {}

No es necesario dar el tipo de dato, el compilador tomará el primer valor que se le pase. Además, las closures, tienen acceso a variables de una scope superior (entorno).

 1struct<T> ??? where T: Fn(i32) -> i32
 2{
 3  closure: T,
 4  result: Option<i32>
 5}
 6
 7impl<T> ???<T> where T: Fn(i32) -> i32 {
 8  fn new(init_closure: T) {
 9    ??? {
10      closure: init_closure,
11      result: None
12    }
13  }
14
15  fn result(&mut self, arg: i32) -> i32 {
16    if self.result == None {
17      self.result = Some(self.closure(arg)); // or Some((self.closure)(arg) ?
18    }
19    self.result
20  }
21}

Tipos de closures como traits:

Anterior: Errores en Rust Volver a Rust Siguiente: Listas y Iteradores