|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "errors" |
| 5 | + "fmt" |
| 6 | + "strconv" |
| 7 | +) |
| 8 | + |
| 9 | +/* |
| 10 | +En golang no existen las excepciones, pero si existen las funciones de manejo de errores. |
| 11 | +
|
| 12 | +Los errores son parte importante de golang porque se decidió desde su diseño inicial, tabajar con ellos |
| 13 | +en vez de excepciones porque estas en la mayoria de los casos no son controladas por el desarrollador |
| 14 | +
|
| 15 | +La idea es que los errores sean controlados apenas se presenten, esta es la razón de que las funciones |
| 16 | +devuelvan multiples valores. Usualmente las funciones como ultimo argumento devuelven un error, para que |
| 17 | +podamos validar si la función ejecutada genera un error y lo podamos controlar. |
| 18 | +
|
| 19 | +Controlar los errores e golang es muy cómodo, además saves siempre de donde viene el error si lo haces |
| 20 | +correctamente. Para controlar los errores y darle más personalización existe el paquete "errors" o |
| 21 | +la función 'errorf' del paquete "fmt", además go, cuenta con funciones como "panic y recover". |
| 22 | +
|
| 23 | +En golang usamos el ok para comprobar errores (Usamos el operador unario con el ok). |
| 24 | +Ok es una variable booleana usada comunmente para verificar si una operación se realizó con éxito, |
| 25 | +premitiendo un manejo más preciso y seguro de los errores y condiciones. |
| 26 | +*/ |
| 27 | + |
| 28 | +// val Variable para guardar el valor obtenido de la conversión en la función |
| 29 | +var val = strToInt("24") |
| 30 | + |
| 31 | +// found Variable que se redefinirá su valor durate los ejercicios y ejemplos |
| 32 | +var found string |
| 33 | + |
| 34 | +// stringToInt Ejemplo 1 de manejo de errores(Simple) |
| 35 | +func strToInt(s string) int { |
| 36 | + num, err := strconv.Atoi(s) |
| 37 | + if err != nil { |
| 38 | + fmt.Println("Error: informacion no válida.", err) |
| 39 | + return -1 |
| 40 | + } |
| 41 | + return num |
| 42 | +} |
| 43 | + |
| 44 | +// errNotFound es una variable que almacena un mensaje personalizado para controlar un error. |
| 45 | +var errNotFound = errors.New("Not Found.") |
| 46 | + |
| 47 | +// fastFood mapa de comida rápida |
| 48 | +var fastFood = map[int]string{ |
| 49 | + 24: "Hamburguesa", 22: "Perro Caliente", 23: "Arroz Chino", 25: "Pizza", |
| 50 | +} |
| 51 | + |
| 52 | +// search funcion de busqueda por un mapa. |
| 53 | +func search(key string) (string, error) { |
| 54 | + num, err := strconv.Atoi(key) |
| 55 | + if err != nil { |
| 56 | + return "", fmt.Errorf("strconv.Atoi: %w", err) |
| 57 | + } |
| 58 | + |
| 59 | + value, err := okVariable(num) |
| 60 | + if err != nil { |
| 61 | + return "", err |
| 62 | + } |
| 63 | + return value, nil |
| 64 | +} |
| 65 | + |
| 66 | +// okVariable Usando el ok y el operador unario y se llama desde search() |
| 67 | +func okVariable(num int) (string, error) { |
| 68 | + value, ok := fastFood[num] |
| 69 | + if !ok { |
| 70 | + return "", fmt.Errorf("OkVariable(): Valor inexistente") |
| 71 | + } |
| 72 | + return value, nil |
| 73 | +} |
| 74 | + |
| 75 | +// animals mapa de animales |
| 76 | +var animals = map[int]string{ |
| 77 | + 1: "Gato", 2: "Perro", 3: "León", |
| 78 | +} |
| 79 | + |
| 80 | +// search funcion de busqueda por un mapa. |
| 81 | +func searchAnimals(key string) (string, error) { |
| 82 | + number, err := strconv.Atoi(key) |
| 83 | + if err != nil { |
| 84 | + return "", fmt.Errorf("strconv.Atoi(): %w", err) |
| 85 | + } |
| 86 | + value, err := findAnimal(number) |
| 87 | + if err != nil { |
| 88 | + return "", fmt.Errorf("findAnimal(): %w", err) |
| 89 | + } |
| 90 | + return value, nil |
| 91 | +} |
| 92 | + |
| 93 | +func findAnimal(num int) (string, error) { |
| 94 | + number, ok := animals[num] |
| 95 | + if !ok { |
| 96 | + return "", errNotFound |
| 97 | + } |
| 98 | + return number, nil |
| 99 | +} |
| 100 | + |
| 101 | +/* |
| 102 | +En estos ejercicios simple no se alcanza a ver la complejidad, por tanto es simple controlarlos así, pero para casos más complejos |
| 103 | +hay que llevar un correcto seguimineto de estos errores,sobretodo cuando hay un anidamiento de procedimientos, |
| 104 | +para eso es muy util el paquete format(fmt) con su función errorf, donde aparte |
| 105 | +de poner texto de error personalizado puedo entregar específicamente desde que funcion o método viene el error. |
| 106 | +*/ |
| 107 | + |
| 108 | +var number1 = 12 |
| 109 | +var number2 = 0 |
| 110 | + |
| 111 | +// division Funcion de division por cero |
| 112 | +func division(n1, n2 int) (int, error) { |
| 113 | + if n2 == 0 { |
| 114 | + return -1, errNotFound |
| 115 | + } |
| 116 | + result := n1 / n2 |
| 117 | + return result, nil |
| 118 | + |
| 119 | +} |
| 120 | + |
| 121 | +// Otra opcion que tiene golang para manejar errores sin se que se detenga la aplicación es con panic y recover |
| 122 | +// Panic se usa para generar un panico tras un error y recover para recuperarse de su error y continuar |
| 123 | +// con las operaciones dejando un mensaje de error. |
| 124 | + |
| 125 | +// extraFunction: Es la función creada para el ejercicio extra de la roadmap |
| 126 | +func extraFunction(n string, n2 int) (int, error) { |
| 127 | + // Con una funcion anónima en una cola de ejecucion con difer, verificamos si se produce un panic y nos recuperamos de él |
| 128 | + defer func() { |
| 129 | + if r := recover(); r != nil { |
| 130 | + fmt.Println("Me recuperé del panic.") |
| 131 | + } |
| 132 | + }() |
| 133 | + |
| 134 | + str, err := strconv.Atoi(n) |
| 135 | + if err != nil { |
| 136 | + return 0, fmt.Errorf("strconv.Atoi(): El parámetro no es válido para operar: %w", err) |
| 137 | + } |
| 138 | + // Validamos si el divisor es igual a cero |
| 139 | + validateZero(n2) |
| 140 | + |
| 141 | + fmt.Printf("No hubo errores, Resultado de dividir %v entre %v: ", str, n2) |
| 142 | + return str / n2, nil |
| 143 | +} |
| 144 | + |
| 145 | +func validateZero(n int) { |
| 146 | + if n == 0 { |
| 147 | + panic("No es posible dividir por cero") |
| 148 | + } |
| 149 | +} |
| 150 | + |
| 151 | +func main() { |
| 152 | + // Primer ejemplo: simple |
| 153 | + fmt.Printf("Value: %d Tipo de datos: %T\n", val, val) |
| 154 | + |
| 155 | + // Segúndo ejemplo: manejo con paquete errors (Personalizado.) |
| 156 | + found, err := search("22") |
| 157 | + if err != nil { |
| 158 | + fmt.Println("search(): ", err) |
| 159 | + return |
| 160 | + } |
| 161 | + fmt.Println(found) |
| 162 | + |
| 163 | + // Tercer ejemplo: comprobación ok con unario. (Uso sin search para buscar el valor directamente) |
| 164 | + found, err = okVariable(val) |
| 165 | + if err != nil { |
| 166 | + fmt.Println("okVariable():", err) |
| 167 | + return |
| 168 | + } |
| 169 | + fmt.Println(found) |
| 170 | + |
| 171 | + // Conprobación espesífica de errores |
| 172 | + found, err = searchAnimals("4") |
| 173 | + if errors.Is(err, errNotFound) { |
| 174 | + fmt.Println("Pudimos controlar el error.") |
| 175 | + return |
| 176 | + } |
| 177 | + if err != nil { |
| 178 | + fmt.Println("searchAnimals(): ", err) |
| 179 | + return |
| 180 | + } |
| 181 | + fmt.Println(found) |
| 182 | + |
| 183 | + // Divición por cero |
| 184 | + div, err := division(number1, number2) |
| 185 | + if err == errNotFound { |
| 186 | + fmt.Println("No es posible dividir por 0") |
| 187 | + return |
| 188 | + } |
| 189 | + fmt.Printf("Resultado de dividir %d entre %d, es: %d\n", number1, number2, div) |
| 190 | + |
| 191 | + // Extra |
| 192 | + divisionExtra, err := extraFunction("12", 2) |
| 193 | + if err != nil { |
| 194 | + fmt.Printf("Mensaje de error: %s, Tipo: %T\n", err, err) |
| 195 | + return |
| 196 | + } |
| 197 | + fmt.Println(divisionExtra) |
| 198 | + fmt.Println("La Ejecución finalizó.") |
| 199 | +} |
0 commit comments