Récapitulatif - File Parser
Fait partie de la section Programmation Orientée Objet du Journey GO de Coddy — leçon 58 sur 107.
Défi
FacileConstruisons un analyseur de fichier de configuration qui regroupe toutes les techniques de gestion d'erreurs de ce chapitre. Votre analyseur gérera plusieurs scénarios d'échec avec des types d'erreurs personnalisés, des erreurs sentinelles, l'emballage d'erreurs (error wrapping) et un nettoyage approprié à l'aide de defer.
Vous organiserez votre code sur trois fichiers :
errors.go: Définissez votre infrastructure d'erreurs pour l'analyseur.Créez deux erreurs sentinelles :
ErrEmptyContentavec le message"file content is empty"ErrInvalidFormatavec le message"invalid configuration format"
Créez un type d'erreur personnalisé
ParseErroravec les champsLine(int) etMessage(string). Sa méthodeError()doit retourner :parse error at line [Line]: [Message]parser.go: Construisez l'analyseur de configuration avec une gestion d'erreurs par couches.Créez une structure
ConfigParseravec un champ booléenparsedpour suivre si l'analyse s'est terminée avec succès.Implémentez ces méthodes :
NewConfigParser() *ConfigParser- crée un nouvel analyseur avecparseddéfini surfalseParseLine(lineNum int, line string) error- valide une seule ligne. Si la ligne ne contient pas de caractère=, retournez un*ParseErroravec le numéro de ligne et le message"missing key-value separator". Sinon, retourneznil.Parse(content string) error- la méthode d'analyse principale qui :- Retourne
ErrEmptyContentsi le contenu est vide - Retourne
ErrInvalidFormatsi le contenu ne contient pas au moins un caractère de saut de ligne - Divise le contenu par sauts de ligne et appelle
ParseLinepour chaque ligne (les numéros de ligne commencent à 1) - Si
ParseLineretourne une erreur, emballez-la avec"parsing configuration: %w"et retournez-la - Définit
parsedsurtrueen cas de succès et retournenil
- Retourne
Status() string- retourne"ready"siparsedest vrai, sinon"not parsed"
main.go: Lisez le contenu de la configuration et démontrez une inspection complète des erreurs.Lisez deux lignes d'entrée qui forment ensemble le contenu de la configuration (joignez-les avec un saut de ligne). Utilisez
deferpour toujours afficher le statut de l'analyseur à la fin, quel que soit le succès ou l'échec.Après avoir tenté l'analyse, inspectez toute erreur en utilisant à la fois
errors.Is()eterrors.As()pour fournir un retour spécifique basé sur ce qui s'est mal passé.
Les entrées suivantes seront fournies :
- Ligne 1 : Première ligne du contenu de la configuration
- Ligne 2 : Deuxième ligne du contenu de la configuration
Gérez les erreurs avec des messages spécifiques :
- Si
errors.Is()trouveErrEmptyContent: affichezError: No configuration provided - Si
errors.Is()trouveErrInvalidFormat: affichezError: Configuration must have multiple lines - Si
errors.As()trouve un*ParseError: affichez l'erreur emballée complète, puis sur une nouvelle ligne affichezFix line [Line]: [Message] - Si l'analyse réussit : affichez
Configuration parsed successfully
Après avoir traité le résultat (succès ou erreur), le statut différé doit s'afficher sur une nouvelle ligne : Parser status: [status]
Par exemple, avec host=localhost et port=8080, votre sortie devrait être :
Configuration parsed successfully
Parser status: readyEt avec host=localhost et invalid line, votre sortie devrait être :
parsing configuration: parse error at line 2: missing key-value separator
Fix line 2: missing key-value separator
Parser status: not parsedEssayez vous-même
package main
import (
"bufio"
"errors"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Lire la première ligne de configuration
line1, _ := reader.ReadString('\n')
line1 = line1[:len(line1)-1] // Supprimer le saut de ligne final
// Lire la deuxième ligne de configuration
line2, _ := reader.ReadString('\n')
if len(line2) > 0 && line2[len(line2)-1] == '\n' {
line2 = line2[:len(line2)-1]
}
// Joindre les deux lignes avec un saut de ligne pour former le contenu de la configuration
content := line1 + "\n" + line2
// Créer un nouveau parseur
parser := NewConfigParser()
// TODO: Utiliser defer pour toujours afficher le statut du parseur à la fin
// Format: "Parser status: [status]"
// TODO: Tenter d'analyser le contenu
// TODO: Gérer les erreurs en utilisant errors.Is() et errors.As()
// - Si errors.Is() trouve ErrEmptyContent: afficher "Error: No configuration provided"
// - Si errors.Is() trouve ErrInvalidFormat: afficher "Error: Configuration must have multiple lines"
// - Si errors.As() trouve un *ParseError: afficher l'erreur complète enveloppée,
// puis sur une nouvelle ligne afficher "Fix line [Line]: [Message]"
// - Si l'analyse réussit: afficher "Configuration parsed successfully"
_ = errors.Is // indice: utiliser errors.Is pour les erreurs sentinelles
_ = errors.As // indice: utiliser errors.As pour les types d'erreurs personnalisés
_ = fmt.Println
}
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO en Go
Fichiers externesEspace de travail et Modules GoPackages et ImportsNoms exportés vs non exportésIntroduction à la POO en GoLes Structs comme ClassesDéfinir des méthodes sur les StructsReceveurs par pointeur vs par valeurInitialisation de StructsFonctions constructeursRécapitulatif - Calculatrice simple4Interfaces
Introduction aux interfacesImplémentation impliciteL'interface comme contratInterface vide (any)Assertion de typeType SwitchComposition d'interfacesInterfaces Stringer & ErrorRécapitulatif - Calculateur de formes7Encapsulation
Champs exportés vs non exportésEncapsulation au niveau du packageMéthodes Getter & SetterMasquage d'informations en GoRécapitulatif - Dossiers étudiants10Génériques (Go 1.18+)
Introduction aux génériquesParamètres de typeContraintes de typeStructures génériquesContournement pour les méthodes génériquesRécapitulatif - Collections génériques13Patrons de conception, Partie 1
Introduction aux Design PatternsPatron SingletonPatron FactoryPatron Abstract FactoryPatron ObserverPatron Strategy2Exploration approfondie des Types et Structs
Types de base et compositesDéfinitions de types personnalisésTags de StructStructs anonymesStructs imbriquéesValeurs par défaut et Zero ValuesRécapitulatif - Carnet de contacts5Composition plutôt qu'héritage
Pourquoi Go n'a pas d'héritageLes bases de l'imbrication de structsPromotion de méthodesImbriquer plusieurs structsImbrication vs AgrégationMasquage de méthodes imbriquéesRécapitulatif - Hiérarchie des employés8Gestion des erreurs & POO
L'interface errorTypes d'erreurs personnalisésError Wrapping (fmt.Errorf)Erreurs sentinelleserrors.Is() et errors.As()Panic, Defer et RecoverRécapitulatif - File Parser11Bibliothèque standard et POO
io.Reader & io.WriterL'interface sort.InterfaceL'interface fmt.Stringerencoding/json avec les StructsL'interface http.HandlerRécapitulatif - Modèles d'API REST14Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositeMiddleware en tant que Décorateur3Pointeurs et Mémoire
Bases des pointeurs en GoPointeurs vers des structsPassage par valeur vs référenceLa fonction new()Garbage Collection en GoRécapitulatif - Constructeur de liste chaînée6Le polymorphisme en Go
Le polymorphisme via les interfacesLe Duck Typing en GoRègles de satisfaction des interfacesCollections polymorphesInjection de dépendancesRécapitulatif - Processeur de paiement9Concurrence et POO
Bases des GoroutinesChannels et CommunicationChannels avec buffer vs sans bufferL'instruction Selectsync.Mutex et sync.RWMutexsync.WaitGroupConception de structures Thread-SafeRécapitulatif - Worker Pool