@@ -178,4 +178,118 @@ De esta forma estamos manejando el posible panico.
178
178
179
179
---
180
180
181
+ ## Errores recuperables
182
+
183
+ Cuando hablamos de "Errores recuperables" nos referimos a errores son errores
184
+ esperables como pueden ser errores del tipo archivo no encontrado, conexión
185
+ rechazada, división por cero, etc.
186
+ No son bugs, sino situaciones previstas que el programa puede manejar.
187
+
188
+ ### 🐹 En Go
189
+
190
+ Go se usa una convención: las funciones devuelven ` (T, error) ` donde ` T ` es el
191
+ tipo de retorno y ` error ` es un tipo de error que representa el error
192
+ ocurrido, si no hay error, el valor de ` error ` es ` nil ` .
193
+ Esto es una convención que se sigue en todo el lenguaje, no es obligatorio pero
194
+ es la forma más común de manejar errores.
195
+ Si la función falla, retorna un error, si no falla, retorna el valor esperado
196
+ y ` nil ` como error.
197
+ Esto es una forma de manejar errores que es bastante simple y directa, pero
198
+ puede resultar un poco verbosa y repetitiva.
199
+ Por ejemplo, si tenemos una función que divide dos números, podría verse así:
200
+
201
+ ``` go
202
+ #package main
203
+ #
204
+ #import " fmt"
205
+ #
206
+ func dividir (a , b int ) (int , error ) {
207
+ if b == 0 {
208
+ return 0 , fmt.Errorf (" división por cero" )
209
+ }
210
+ return a / b, nil
211
+ }
212
+ #
213
+ #func main () {
214
+ # resultado , err := dividir (10 , 0 )
215
+ # if err != nil {
216
+ # fmt.Println (" Error:" , err)
217
+ # return
218
+ # }
219
+ # fmt.Println (" Resultado:" , resultado)
220
+ #}
221
+ ```
222
+
223
+ Donde si ` b ` es cero, retornamos un error, si no, retornamos el resultado
224
+ y ` nil ` como error.
225
+
226
+ ### 🦀 En Rust
227
+
228
+ Rust usa el tipo ` Result<T, E> ` para manejar errores recuperables, donde ` T ` es
229
+ el tipo de retorno y ` E ` es el tipo de error.
230
+ El tipo ` Result ` es un enum que puede ser ` Ok(T) ` o ` Err(E) ` :
231
+
232
+ ``` rust
233
+ enum Result <T , E > {
234
+ Ok (T ),
235
+ Err (E ),
236
+ }
237
+ ```
238
+
239
+ Lo que permite manejar errores de forma más explícita y segura, nos garantiza
240
+ seguridad, o falla o nos devuelve el resultado esperado pero imposibilita el
241
+ obtener ambos valores.
242
+ Por ejemplo, si tenemos una función que divide dos números, podría verse así:
243
+
244
+ ``` rust
245
+ fn dividir (a : i32 , b : i32 ) -> Result <i32 , String > {
246
+ if b == 0 {
247
+ Err (" División por cero" . to_string ())
248
+ } else {
249
+ Ok (a / b )
250
+ }
251
+ }
252
+ #
253
+ #fn main () {
254
+ # match dividir (10 , 0 ) {
255
+ # Ok (resultado ) => println! (" Resultado: {}" , resultado ),
256
+ # Err (e ) => println! (" Error: {}" , e ),
257
+ # }
258
+ #}
259
+ ```
260
+
261
+ En este caso, si ` b ` es cero, retornamos un ` Err ` con un mensaje de error,
262
+ si no, retornamos un ` Ok ` con el resultado de la división.
263
+
264
+ Es más explicito el path al decir que algo es un error, y no es necesario
265
+ retornar un valor adicional como en Go, ya que el ` Result ` ya nos indica si
266
+ hubo un error o no.
267
+
268
+ En Go funciona como una tupla en Rust como un enum.
269
+
270
+ Sin embargo en Rust los errores no se pueden ignorar, si no se maneja el
271
+ ` Result ` , el compilador nos dará un error de compilación, lo que nos obliga
272
+ a manejar los errores de forma explícita.
273
+
274
+ Este es el manejo de errores más simple en Rust, y se encuentra en esta sección
275
+ porque es facilmente comparable con el manejo de errores en Go.
276
+
277
+ Sin embargo, Rust tiene un sistema de manejo de errores mucho más avanzado y
278
+ flexible que permite manejar errores de forma más eficiente, permitiendo
279
+ propagación (una de las funcionalidades más queridas en Go), conversiones de
280
+ tipo y dando seguridad en todos los casos, todo esto lo veremos en la sección
281
+ de Manejo de Errores Avanzados.
282
+
283
+ ### Comparativa de manejo de errores
284
+
285
+ Aquí una tabla comparativa entre Rust y Go para el manejo de errores
286
+
287
+ | | ** Rust** | ** Go** |
288
+ | ------------------------ | --------------------------------- | --------------------------------- |
289
+ | ¿Cómo se manejan? | ` Result<T, E> ` | ` (T, error) ` |
290
+ | ¿Qué tipo de error? | ` enum Result<T, E> ` | ` error ` (interfaz) |
291
+ | ¿Obliga a manejarlo? | ✅ Sí (el compilador lo exige) | ❌ No (convención ` if err != nil ` )|
292
+ | ¿Qué pasa si lo ignorás? | ⚠️ Warning o error de compilación | 🚫 Nada, se puede ignorar |
293
+ | ¿Propagación de errores? | ✅ | ✅ Con ` return ` o ` defer ` |
294
+
181
295
0 commit comments