Errores en Go - Uso de err ≠ nil
No, en Go, nil no es interpretado como 0. El valor nil en Go representa la ausencia de valor o la falta de inicialización para ciertos tipos, como pointers, slices, maps, channels, interfaces, funcs..
Cuando ves una comparación como != nil, no significa que se esté comparando con el número 0, sino que se está verificando si la variable ha sido inicializada o no. Si una variable de alguno de estos tipos tiene el valor nil, significa que no ha sido inicializada correctamente y, por lo tanto, intentar operar con ella causaría un error en tiempo de ejecución.
Ejemplo para map:
En este caso, el mapa m
está en su estado cero, que es nil
, porque no ha sido inicializado con make
. Si intentas agregar un valor a m
sin inicializarlo, obtendrás un panic.
Err ≠ nil
Cuando ves la expresión err != nil
en Go, significa que el programa está verificando si ha ocurrido un error.
En Go, muchas funciones devuelven un valor de error (error
), que es una interfaz predefinida en el lenguaje. Si no ha ocurrido ningún error, la función devolverá nil
como valor para el error
, lo que indica que todo salió bien. Sin embargo, si ocurre un error, la función devolverá un valor que no es nil
, y este valor contendrá información sobre el tipo de error que ocurrió.
Por eso, la verificación err != nil
es una forma de comprobar si existe un error (si el valor de err
no es nil
, significa que algo salió mal).
Ejemplo típico:
Resumen:
err == nil
→ No hay error, todo está bien.err != nil
→ Ocurrió un error, y deberías manejarlo.
La interfaz error()
error()
El tipo error
en Go es una interfaz predefinida en el lenguaje, y su definición es la siguiente:
Esto significa que cualquier valor que implemente el método Error()
que retorne una cadena (string
) es considerado un valor de tipo error
. Cuando una función devuelve un error
, puede ser nil
(si no hubo errores) o un valor que implemente Error()
(si hubo algún error).
Así que, en resumen:
err
es solo una convención común para nombrar variables de error.El tipo de
err
eserror
, que es una interfaz predefinida en Go.
Err se pasa como parametro o como es que se maneja el error para pasar de segundo?
Ejemplo
En este caso, os.Open
no recibe dos parámetros. La función Open
solo recibe un parámetro: el nombre del archivo como una cadena (string
). Lo que pasa es que devuelve dos valores: un descriptor de archivo (file
) y un valor de error (err
).
En Go, no se pasa un parámetro adicional de tipo error
para el manejo de errores, sino que las funciones que pueden fallar devuelven un valor de tipo error
como parte de sus retornos. El patrón común es que una función retorne tanto el resultado deseado como un valor de error, y luego tú como desarrollador verificas ese valor de error.
Ejemplo:
Aquí, la función
hacerAlgoComplejo
devuelve un entero (int
) y un error (error
).Si algo sale mal dentro de la función, se devuelve un error usando
fmt.Errorf
, pero no se recibe un parámetro de tipoerror
.Al llamar a la función, verificas si el error ocurrió:
Conclusión:
Cuando creas funciones complejas, no necesitas pasar un parámetro de tipo error
a la función, sino que deberías hacer que la función devuelva un valor de tipo error
cuando algo falle. Luego, al usar la función, verificas ese valor de error (err
) para asegurarte de que todo esté funcionando correctamente.
Es una buena práctica que tus funciones retornen un valor de tipo error
cuando sea necesario y que manejes esos errores de forma explícita en el código que llama a la función.
Preguntas para practicar:
¿Cuál es la diferencia entre la longitud y la capacidad de un slice?
¿Qué ocurre cuando modificas un slice que proviene de un array?
Si creas un slice desde un array, ¿modificar el slice afecta el array original? Explica por qué.
Escribe una función que acepte un slice de enteros y devuelva el promedio de esos enteros.
¿Qué hace la función
append()
internamente si se excede la capacidad del slice?
Mis respuestas:
Correcto. La longitud (
len
) es el número de elementos que actualmente contiene el slice, mientras que la capacidad (cap
) es el número de elementos que puede contener antes de que Go redimensione el slice.Parcialmente correcto. Modificar un slice afecta al array original si el slice aún está basado en el array subyacente. Los slices no son independientes del array; al contrario, comparten memoria. Así que, si modificas un slice, esos cambios se reflejan en el array original.
Incorrecto. Los slices no son copias del array original. Si creas un slice a partir de un array, ambos compartirán la misma memoria. Modificar el slice también modifica el array original, ya que ambos están referenciando la misma región de memoria.
Código incorrecto. En tu función, hay algunos problemas:
No has inicializado la variable
suma
.Estás usando índices incorrectos dentro del loop.
Además, la función debería devolver
float64
porque estamos calculando un promedio.
Aquí te dejo la corrección:
Incorrecto. Cuando
append()
excede la capacidad del slice, no retorna un error ni unpanic
. En lugar de eso, Go crea un nuevo array con mayor capacidad, copia los elementos del array original a este nuevo array, y luego agrega el nuevo elemento. El slice devuelto apunta a este nuevo array.
Last updated