En Go, se pueden declarar explícitamente los nombres de los valores de retorno en la firma de la función. Estos valores se inicializan automáticamente con el zero value de su tipo. Esto es conveniente al trabajar con un gran número de variables de retorno, ya que permite "retornar" implícitamente valores a través de la instrucción return (sin argumentos).
Ejemplo:
func foo() (x int, err error) { if someCheck() { x = 1 return // regresará (1, nil) } return // regresará (0, nil), si x y err no fueron asignados explícitamente }
Detalles:
nil para error). Esto puede ocultar errores en la lógica.¿Qué devolverá una función con resultados nombrados si no hay ninguna asignación a las variables de retorno y se llama simplemente a return?
Respuesta: Se devolverán sus zero values. Por ejemplo, para int — 0, para un puntero — nil.
Ejemplo:
func test() (res *MyType, code int) { return // lo mismo que "return nil, 0" }
Historia
En un servicio financiero, olvidaron asignar un valor a la variable err (error) dentro de una función con retornos nombrados. Como resultado, en un fallo, la función devolvía nil y el error se perdía. Esto rompió el procesamiento de transacciones, y algunas operaciones pasaron desapercibidas.
Historia
Al refactorizar una función, se agregó un nuevo resultado de retorno nombrado, pero la incompatibilidad con el tipo de retorno anterior no fue notada — las pruebas pasaron por alto el problema porque se devolvió un valor nulo, lo que llevó a un bug silencioso en el almacenamiento.
Historia
En una de las funciones auxiliares, se registraban errores a través del resultado nombrado, pero a veces se olvidaban de manejarlos no solo al retornar, sino también en el registro, lo que resultaba en bugs difíciles de reproducir ("error lost").