Manejo de errores y uso de If

8/42
Recursos
Transcripción

Aportes 22

Preguntas 2

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

El manejo de errores dentro de go es un tanto más simple que en otros lenguajes de programación dado que las funciones pueden regresar varios valores. La norma dentro de Go es que las funciones regresen 2 valores usualmente: el valor esperado y un error. Esto quiere decir que si fue exitoso el valor esperado se recibe normalmente y un error con un valor de nil. En el caso opuesto de si hubo un error el valor esperado se recibe como nil y se recibe también el error con su valor correspondiente.

val, err := foo.Func(args) 
if err != nil {
	fmt.Println("Hubo un error")
}

// Continúa la ejecución ...
		

Genial 😃 una pena que no tenga try

Se puede concatenar mensajes en el Println ? Es decir porque sale error si trato de hacer lo siguiente: fmt.Println(“Ocurrió un error” + err1). Espero que alguien me resuleva la duda , gracis

Regresa un error.

el manejo del error es muy interesante.

Interesante es similar a como se reciben datos de una promesa en Javascript.
Me parece una manera bastante elegante de hacerlo en go .

Golang cuando consigue un error te regresa pero cuando no te regresa un valor nill

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	fmt.Println("Por favor introduzca la operacion a realizar")
	scanner.Scan()
	operacion := scanner.Text()
	fmt.Println(operacion)
	valores := strings.Split(operacion, "+")
	fmt.Println(valores)

	operador1, error1 := strconv.Atoi(valores[0])
	operador2, _ := strconv.Atoi(valores[1])

	if error1 != nil {
		fmt.Println(error1)
	} else {
		fmt.Println(operador1)
	}
	resultado := operador1 + operador2
	fmt.Println(resultado)
}

La clase es simple pero tan reveladora. Al desarrollador novato no se le ocurre que alguna vez puede fallar su solución, estas cosas nos ayudan a tener soluciones robustas.

Algo brutal que me acabo de dar cuenta es que un puede pasar una funcion como argumento de otra funcion!

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	operacion := scanner.Text()
	fmt.Println(operacion)
	operacion = strings.ReplaceAll(operacion, " ", "")
	valores := strings.Split(operacion, "+")
	fmt.Println(valores)
	operandoOne, err := strconv.Atoi(valores[0])

	if err != nil {
		fmt.Println("Number", operandoOne, "Error", err)
	} else {
		fmt.Println("Soo god")
	}

	operandoTwo, _ := strconv.Atoi(valores[1])
	performOperator(operandoOne, operandoTwo, plusOpetator)
}

func performOperator(x int, y int, f func(int, int) int) {
	fmt.Println(f(x, y))
}

func plusOpetator(x int, y int) int {
	return x + y
}


Interesante

Siento que ese tipo de errores es mejor manejarlos con un try catch en lugar de un if

Así hice yo la conversión de string a números

operator1, _ := strconv.ParseFloat(values[0], 64) operator2, _ := strconv.ParseFloat(values[1], 64)

📟🤙

func main() {
	scanner := bufio.NewScanner(os.Stdin)

	scanner.Scan()

	operacion := scanner.Text()
	valores := strings.Split(operacion, "+")

	operador1, err1 := strconv.Atoi(valores[0])
	operador2, err2 := strconv.Atoi(valores[1])

	if err1 != nil || err2 != nil {
		fmt.Println("Syntax Error")
	} else {
		fmt.Println(operador1 + operador2)
	}```

En Go, los errores inesperados también pueden manejarse con la función panic(<message>) de tal forma que quedaría así:

if err != nil {
	panic(err)
}

al hacer esto, el programa se va a dentendrá e imprimirá en consola el error.

Algo que me facilito la compresión del manejo de errores en Goland, es que el error es otro tipo de dato mas que nos ayuda en el flujo de control de nuestra aplicación.

Comparto mi código del ejercicio de la calculadora con algunas variaciones

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

const separador = "+"

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()

	operacion := scanner.Text()
	valores := dividirOperacion(operacion)
	operadores, err := convertirValores(valores)
	if err != nil {
		fmt.Println(err)
		return
	}
	resultado := sumarOperadores(operadores)
	fmt.Println("Resultado: ", resultado)
}

func dividirOperacion(operacion string) []string {
	return strings.Split(operacion, separador)
}

func convertirValores(valores []string) ([]int, error) {
	var numeros []int
	for i := 0; i < len(valores); i++ {
		if numero, err := strconv.Atoi(valores[i]); err != nil {
			return nil, err
		} else {
			numeros = append(numeros, numero)
		}
	}
	return numeros, nil
}

func sumarOperadores(operadores []int) int {
	var resultado int
	for i := 0; i < len(operadores); i++ {
		resultado = resultado + operadores[1]
	}
	return resultado
}

¿Cómo así que la función devuelve dos valores?
Bueno, aquí un ejemplo de una función que devuelve 4 valores pero en el mismo programa solo tomamos 2 y los 2 restantes los ignoramos (Las funciones pueden devolver la cantidad de valores que sean).

package main

import "fmt"

func swap(x, y string) (string, string, string, string) {
	return y, x, x + y, y + x
}

func main() {
	a, b, _, _ := swap("hello", "world")
	fmt.Println(a, b)
}

En lo personal creo que es más chevere poner los errores con log.fatal

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strconv"
	"strings"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	fmt.Println("Ingrese una suma con 2 operadores")
	scanner.Scan()
	operation := scanner.Text()
	values := strings.Split(operation, "+")

	operator1, e1 := strconv.Atoi(values[0])
	if e1 != nil {
		log.Fatal("El primer parámetro falló\n", e1)
	}
	operator2, e2 := strconv.Atoi(values[1])
	if e2 != nil {
		log.Fatal("El segundo parámetro falló\n", e2)
	}

	result := operator1 + operator2
	fmt.Println("El resultado es", result)
}

Mi codigo

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
	"strconv"
)

func main()  {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	operacion := scanner.Text()
	fmt.Println(operacion)
	valores := strings.Split(operacion, "+")
	fmt.Println(valores)
	fmt.Println(valores[0] + valores[1])
	operador1, err1 := strconv.Atoi(valores[0])
	if err1 != nil {
		fmt.Println(err1)
	} else {
		fmt.Println(operador1)
	}

	operador2, err2 := strconv.Atoi(valores[1])
	if err2 != nil {
		fmt.Println(err2)
	} else {
		fmt.Println(operador2)
	}

	if err1 == nil && err2 == nil {
		fmt.Println(operador1 + operador2)
	} else {
		fmt.Println("no se pudo hacer la operacion")
	}
}

Uso de if y else con lo que vimos hasta ahora.
Genere unas funciones adicionales para no repetir taaaaaanto código.
También anide los if-else

Espero que les sirva

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {

	mensajeBienvenida()

	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	operacion := scanner.Text()

	fmt.Println(operacion)
	fmt.Println("----------------------------")
	valores := strings.Split(operacion, "+")
	fmt.Println("----------------------------")

	// Frase del capitulo anterior:
	// Atoi regresa dos valores.
	// El primer valor contiene el string convertido al nuevo tipo de dato.
	// El segundo es un codigo de error (por si las cosas salen mal)
	// Como este caso no se utiliza el código de error Golang provee una forma de almacenarlo
	// dentro de una variable anonima mediante el operador "_" (guion bajo)
	// Lo que nos adelanta que Golang como en otros lenguajes de programación permite la inicialización
	// de varias variables en una linea, a saber:
	// nombre, apellido := "Ezequiel", "Pettinari"
	// fmt.Println("Nombre: " + nombre)
	// fmt.Println("Apellido: " + apellido)

	// A esta altura, habras probado que pasa al ingresar valores que no pueden ser convertidos a numeros...
	//
	// Siguiendo esta linea argumental, procedemos a nombrar la segunda variable con un identificador
	// que nos permite capturar ese error.
	// Al asignarlo debemos utilizarlo si o si.
	// Por este motivo, debemos manipular ese error.
	// Si el error esta definido nos devuelve el error que se produjo.
	// Si no esta definido nos devuelve un valor nulo que en Golang se define como "nil"

	//Declaración e inicialización de las variables primer_operador y error1
	primerOperador, error1 := strconv.Atoi(valores[0])

	//Declaración e inicialización de las variables segundo_operador y error2
	segundoOperador, error2 := strconv.Atoi(valores[1])

	// Utilización de condicional if-else
	// Si el error1 no es nulo ó Si el error2 no es nulo
	// Es decir, pusiste cualquier cosa en cualquiera de las dos variables...
	if (error1 != nil) || (error2 != nil) {

		// Si error1 no es nulo, imprime el mensaje de error
		// De otra forma, imprime el valor del primer operador
		if error1 != nil {

			capturarError(error1)

		} else {

			fmt.Println("Hola, soy el primer operador de tu suma: ")
			fmt.Println(primerOperador)

		}

		// Si error2 no es nulo, imprime el mensaje de error
		// De otra forma, imprime el valor del segundo operador
		if error2 != nil {

			capturarError(error2)

		} else {
			fmt.Println("Hola, soy el segundo operador de tu suma: ")
			fmt.Println(segundoOperador)

		}

	} else {

		// Sino sumate esos dos operadores!!!!!
		// Mira que programa che

		suma(primerOperador, segundoOperador)

	}

	fmt.Println("----------------------------")
	fmt.Println("Fin del programa")
	fmt.Println("----------------------------")

}

// suma se encarga de sumar los dos operadores
func suma(pPrimerOperador, pSegundoOperador int) {

	fmt.Println("----------------------------")
	fmt.Println("Resultado de la operación aritmética:")
	fmt.Println(pPrimerOperador + pSegundoOperador)
	fmt.Println("----------------------------")

}

// mensajeBienvida muestra el mensaje de comienzo de programa
func mensajeBienvenida() {

	// Separador elegante 8)
	fmt.Println("----------------------------")
	fmt.Println("Comienzo del programa")
	fmt.Println("----------------------------")
	fmt.Println("Por favor, ingrese la operación que desea realizar")
	fmt.Println("Solo suma por ahora (Pleaaaasseeeeee)")
	fmt.Println("----------------------------")

}

// funcion para capturar el mensaje de error y mostrarla en pantalla
func capturarError(pMensajeError error) {

	fmt.Println("----------------------------")
	fmt.Println("Houston, tenemos un problema:")
	fmt.Println(pMensajeError)
	fmt.Println("----------------------------")

}
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main()  {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	operation := scanner.Text()
	fmt.Println(operation)
	values := strings.Split(operation, "+")
	fmt.Println(values)
	fmt.Println(values[0] + values[1])
	operator1, err1 := strconv.Atoi(values[0])
	if err1 != nil {
		fmt.Println(err1)
	}else {
		fmt.Println(operator1)
	}
	operator2, err2 := strconv.Atoi(values[1])

	if err2 != nil {
		fmt.Println(err2)
	}else {
		fmt.Println(operator2)
	}
	
	fmt.Println(operator1 + operator2)
}