Resumen - Analizador de archivos
Parte de la sección Programación Orientada a Objetos del Journey de GO de Coddy. Lección 58 de 107.
Desafío
FácilConstruyamos un analizador de archivos de configuración que reúna todas las técnicas de manejo de errores de este capítulo. Tu analizador gestionará varios escenarios de fallo con tipos de error personalizados, errores centinela, envoltorio de errores y una limpieza adecuada mediante defer.
Organizarás tu código en tres archivos:
errors.go: Define la infraestructura de errores para el analizador.Crea dos errores centinela:
ErrEmptyContentcon el mensaje"file content is empty"ErrInvalidFormatcon el mensaje"invalid configuration format"
Crea un tipo de error personalizado
ParseErrorcon los camposLine(int) yMessage(string). Su métodoError()debe devolver:parse error at line [Line]: [Message]parser.go: Construye el analizador de configuración con manejo de errores por capas.Crea una estructura
ConfigParsercon un campo booleanoparsedpara realizar un seguimiento de si el análisis se completó correctamente.Implementa estos métodos:
NewConfigParser() *ConfigParser- crea un analizador nuevo conparsedestablecido enfalseParseLine(lineNum int, line string) error- valida una sola línea. Si la línea no contiene un carácter=, devuelve un*ParseErrorcon el número de línea y el mensaje"missing key-value separator". De lo contrario, devuelvenil.Parse(content string) error- el método principal de análisis que:- Devuelve
ErrEmptyContentsi el contenido está vacío - Devuelve
ErrInvalidFormatsi el contenido no contiene al menos un carácter de nueva línea - Divide el contenido por las nuevas líneas y llama a
ParseLinepara cada línea (los números de línea comienzan en 1) - Si
ParseLinedevuelve un error, lo envuelve con"parsing configuration: %w"y lo devuelve - Establece
parsedentruesi todo tiene éxito y devuelvenil
- Devuelve
Status() string- devuelve"ready"siparsedes true; de lo contrario, devuelve"not parsed"
main.go: Lee el contenido de la configuración y muestra una inspección completa de los errores.Lee dos líneas de entrada que juntas forman el contenido de la configuración (únelas con una nueva línea). Usa
deferpara imprimir siempre el estado del analizador al final, independientemente de que la operación tenga éxito o falle.Después de intentar analizar el contenido, inspecciona cualquier error usando tanto
errors.Is()comoerrors.As()para proporcionar información específica según lo ocurrido.
Se proporcionarán las siguientes entradas:
- Línea 1: Primera línea del contenido de la configuración
- Línea 2: Segunda línea del contenido de la configuración
Maneja los errores con mensajes específicos:
- Si
errors.Is()encuentraErrEmptyContent: imprimeError: No configuration provided - Si
errors.Is()encuentraErrInvalidFormat: imprimeError: Configuration must have multiple lines - Si
errors.As()encuentra un*ParseError: imprime el error envuelto completo y, después, en una nueva línea imprimeFix line [Line]: [Message] - Si el análisis tiene éxito: imprime
Configuration parsed successfully
Después de gestionar el resultado (éxito o error), el estado diferido debe imprimirse en una nueva línea: Parser status: [status]
Por ejemplo, dados host=localhost y port=8080, la salida debe ser:
Configuration parsed successfully
Parser status: readyY dados host=localhost y invalid line, la salida debe ser:
parsing configuration: parse error at line 2: missing key-value separator
Fix line 2: missing key-value separator
Parser status: not parsedPruébalo tú mismo
package main
import (
"bufio"
"errors"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Leer la primera línea de configuración
line1, _ := reader.ReadString('\n')
line1 = line1[:len(line1)-1] // Eliminar el salto de línea final
// Leer la segunda línea de configuración
line2, _ := reader.ReadString('\n')
if len(line2) > 0 && line2[len(line2)-1] == '\n' {
line2 = line2[:len(line2)-1]
}
// Unir las dos líneas con un salto de línea para formar el contenido de la configuración
content := line1 + "\n" + line2
// Crear un nuevo analizador (parser)
parser := NewConfigParser()
// TODO: Usar defer para imprimir siempre el estado del analizador al final
// Formato: "Parser status: [status]"
// TODO: Intentar analizar el contenido
// TODO: Manejar errores usando errors.Is() y errors.As()
// - Si errors.Is() encuentra ErrEmptyContent: imprimir "Error: No configuration provided"
// - Si errors.Is() encuentra ErrInvalidFormat: imprimir "Error: Configuration must have multiple lines"
// - Si errors.As() encuentra un *ParseError: imprimir el error envuelto completo,
// luego en una nueva línea imprimir "Fix line [Line]: [Message]"
// - Si el análisis tiene éxito: imprimir "Configuration parsed successfully"
_ = errors.Is // pista: usar errors.Is para errores centinela
_ = errors.As // pista: usar errors.As para tipos de error personalizados
_ = fmt.Println
}
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de POO en Go
Archivos externosEspacio de trabajo y módulos de GoPaquetes e importacionesNombres exportados vs. no exportadosIntroducción a la POO en GoStructs como clasesDefinición de métodos en structsReceptores de puntero vs. de valorInicialización de structsFunciones constructorasResumen - Calculadora simple4Interfaces
Introducción a las interfacesImplementación implícitaLa interfaz como contratoInterfaz vacía (any)Type AssertionType SwitchComposición de interfacesInterfaces Stringer y ErrorResumen: Calculadora de figuras7Encapsulamiento
Campos exportados vs. no exportadosEncapsulamiento a nivel de paqueteMétodos Getter y SetterOcultamiento de información en GoResumen - Registros de estudiantes10Genéricos (Go 1.18+)
Introducción a los GenéricosParámetros de tipoRestricciones de tipoStructs genéricosSolución alternativa para métodos genéricosResumen - Colección genérica13Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón Abstract FactoryPatrón ObserverPatrón Strategy2Inmersión profunda en Tipos y Structs
Tipos básicos y compuestosDefiniciones de tipos personalizadosEtiquetas de StructsStructs anónimosStructs anidadosValores cero y por defectoRepaso - Libreta de contactos5Composición sobre herencia
Por qué Go no tiene herenciaConceptos básicos de incrustación de structsPromoción de métodosIncrustación de múltiples structsIncrustación vs AgregaciónShadowing de métodos incrustadosResumen - Jerarquía de empleados8Manejo de Errores y OOP
La interfaz errorTipos de errores personalizadosEnvoltura de errores (fmt.Errorf)Errores centinelaerrors.Is() y errors.As()Panic, Defer y RecoverResumen - Analizador de archivos3Punteros y Memoria
Fundamentos de punteros en GoPunteros a StructsPaso por valor vs referenciaLa función new()Garbage Collection en GoResumen - Constructor de Linked List6Polimorfismo en Go
Polimorfismo mediante interfacesDuck Typing en GoReglas de satisfacción de interfacesColecciones polimórficasInyección de dependenciasResumen - Procesador de pagos9Concurrencia y POO
Fundamentos de GoroutinesChannels y comunicaciónChannels con buffer vs. sin bufferSentencia Selectsync.Mutex y sync.RWMutexsync.WaitGroupDiseño de estructuras Thread-SafeResumen - Worker PoolPractica por tu cuenta: Compilador de Go online