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:
FnOnce
: toma ownership de las variables de su entorno. Solo se puede llamar una vez, porque al tomar ownership luego se borran (move || {}
).FnMut
: mutably borrow valueFn
: immutably borrow value