@@ -6,8 +6,85 @@ funciones, estructuras y tipos que funcionan con múltiples tipos sin duplicar
6
6
la lógica.
7
7
8
8
Antes de los genéricos, en Go era común ver duplicación de funciones para
9
- distintos tipos:
9
+ distintos tipos o declaraciones de tipos utilizando interfaces.
10
10
11
+ Pero también podríamos crear un único tipo de dato, posteriormente a la llegada
12
+ de Go 1.8 podemos empezar a encontrarnos código así:
13
+
14
+ {{#tabs }}
15
+ {{#tab name="Go antes de v1.8" }}
16
+
17
+ ``` go
18
+ #package main
19
+ #
20
+ #import " fmt"
21
+ #
22
+ type Caja struct {
23
+ valor interface {}
24
+ }
25
+ #
26
+ #func main () {
27
+ # c := Caja {valor: 42 }
28
+ # fmt.Println (c.valor ) // 42
29
+ #
30
+ # c2 := Caja {valor: " hola" }
31
+ # fmt.Println (c2.valor ) // hola
32
+ #
33
+ # // Si querés operar con el valor, tenés que hacer type assertion
34
+ # if v , ok := c.valor .(int ); ok {
35
+ # fmt.Println (v + 10 ) // 52
36
+ # } else {
37
+ # fmt.Println (" No es un int" )
38
+ # }
39
+ #}
40
+ ```
41
+
42
+ {{#endtab }}
43
+ {{#tab name="Go despues de v1.8" }}
44
+
45
+ ``` go
46
+ #package main
47
+ #
48
+ #import " fmt"
49
+ #
50
+ type Caja [T any] struct {
51
+ valor T
52
+ }
53
+ #
54
+ #func main () {
55
+ # c := Caja [int ]{valor: 42 }
56
+ # fmt.Println (c.valor )
57
+ #
58
+ # c2 := Caja [string ]{valor: " hola" }
59
+ # fmt.Println (c2.valor )
60
+ #}
61
+ ```
62
+ {{#endtab }}
63
+ {{#endtabs }}
64
+
65
+ Rust tiene desde la primera versión genéricos por lo que no existe tal división
66
+ y el mismo código de ejemplo se podría ver de la siguiente forma:
67
+
68
+ ``` rust
69
+ struct Caja <T > {
70
+ valor : T ,
71
+ }
72
+ #
73
+ #fn main () {
74
+ # let c = Caja { valor : 42 };
75
+ # println! (" {}" , c . valor);
76
+ #
77
+ # let c2 = Caja { valor : String :: from (" hola" ) };
78
+ # println! (" {}" , c2 . valor);
79
+ #}
80
+ ```
81
+
82
+
83
+ En el caso de las funciones genéricas con Go obtendríamos un código similar a
84
+ este:
85
+
86
+ {{#tabs }}
87
+ {{#tab name="Go antes de v1.8" }}
11
88
``` go
12
89
func SumarInts (a , b int ) int {
13
90
return a + b
@@ -18,16 +95,21 @@ func SumarFloats(a, b float64) float64 {
18
95
}
19
96
```
20
97
21
- Con genéricos, esa duplicación desaparece:
22
-
98
+ {{#endtab }}
99
+ {{#tab name="Go despues de v1.8" }}
23
100
``` go
24
101
func Sumar [T int | float64 ](a, b T ) T {
25
102
return a + b
26
103
}
27
104
```
105
+ {{#endtab }}
106
+ {{#endtabs }}
28
107
29
- A diferencia de Go, Rust no se suele especificar el tipo de dato en el genérico,
30
- lo que se especifica es el comportamiento del tipo de dato.
108
+ A diferencia de Go, en Rust no se suele especificar el tipo de dato en el
109
+ genérico, lo que se especifica es el comportamiento del tipo de dato.
110
+
111
+ Rust evita en multiples aspectos las concreciones, lo cual nos permite código
112
+ más abstraído.
31
113
32
114
<div class =" info " >
33
115
@@ -59,8 +141,8 @@ fn sumar(a: &Numero, b: &Numero) -> Numero {
59
141
}
60
142
```
61
143
62
- No se suele discriminar por ` struct ` o variante sino por el ` trait ` , el
63
- comportamiento como tal porque si sabemos los tipos concretos que debemos
144
+ No se suele discriminar por ` struct ` o variante de ` enum ` sino por el ` trait ` ,
145
+ el comportamiento como tal porque si sabemos los tipos concretos que debemos
64
146
utilizar entonces no necesitamos genéricos.
65
147
66
148
También ** es posible que en el futuro** esta feature de Go y muchos otros
@@ -72,13 +154,14 @@ discusiones oficiales.
72
154
73
155
</details >
74
156
75
- O simplemente como dijimos al comienzo dos funciones.
76
-
157
+ Si hablamos de concreciones es posible que con crear las funciones a mano
158
+ también sea una buena idea en lugar de usar un genérico una lista de
159
+ tipos de datos específicos.
77
160
78
161
</div >
79
162
80
- Es por eso que esto tiene relación con los ` traits ` como veremos un poco más
81
- abajo.
163
+ Debido a esta idea de buscar abstracciones es por eso que esto tiene relación
164
+ con los ` traits ` como veremos un poco más abajo con los ` trait bounds ` .
82
165
83
166
## Polimorfismo con ` static dispatch `
84
167
@@ -239,7 +322,7 @@ fn procesar<T>(io: T) where T: Read + Write {
239
322
Los trait bounds se pueden componer de distintas formas. Esto permite crear
240
323
funciones que trabajen con tipos muy específicos sin perder generalidad.
241
324
242
- A medida que avancemos en nuestro expertis en Rust podremos notar que esto
325
+ A medida que avancemos en nuestro expertiz en Rust podremos notar que esto
243
326
nos ayuda a generar APIs de librerias y experiencia de desarrollo realmente
244
327
buena, simplificando muchas cosas.
245
328
0 commit comments