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(鈥淥curri贸 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)
}