Récapitulatif - Division sécurisée
Fait partie de la section Logique & Flux du Journey GO de Coddy — leçon 44 sur 68.
Défi
FacileConstruisez une calculatrice mathématique complète qui implémente une division sécurisée avec plusieurs types d'erreurs personnalisés et une gestion d'erreurs appropriée. Ce défi combine des types d'erreurs personnalisés, l'emballage d'erreurs (error wrapping) et la vérification d'erreurs pour créer un système robuste qui gère gracieusement divers échecs d'opérations mathématiques.
Vous recevrez deux entrées :
- Une chaîne contenant les détails de l'opération au format
"operation,num1,num2,precision"(par exemple,"divide,10,0,2") - Une chaîne contenant les paramètres de la calculatrice au format
"calculator_name,mode"(par exemple,"ScientificCalc,strict")
Votre tâche consiste à :
- Créer deux types d'erreurs personnalisés :
- Une structure
DivisionErroravec les champsDividend(float64) etDivisor(float64) - Une structure
ValidationErroravec les champsField(string) etValue(float64)
- Une structure
- Implémenter la méthode
Error() stringpourDivisionErrorqui retourne :"division error: cannot divide [dividend] by [divisor]" - Implémenter la méthode
Error() stringpourValidationErrorqui retourne :"validation error: invalid [field] value [value]" - Analyser la première entrée en la divisant par les virgules pour obtenir l'opération, num1, num2 et la précision
- Analyser la seconde entrée en la divisant par les virgules pour obtenir le nom de la calculatrice et le mode
- Convertir les nombres sous forme de chaîne en float64 et la précision en int
- Créer une fonction
safeDividequi prend deux paramètres float64 et retourne (float64, error) :- Si le diviseur est 0, retourner 0 et une
DivisionErroravec les valeurs du dividende et du diviseur - Si le dividende est négatif et que le mode est
"strict", retourner 0 et uneValidationErroravec le champ"dividend"et la valeur du dividende - Si le diviseur est négatif et que le mode est
"strict", retourner 0 et uneValidationErroravec le champ"divisor"et la valeur du diviseur - Sinon, retourner le résultat de la division et nil
- Si le diviseur est 0, retourner 0 et une
- Créer une fonction
performCalculationqui enveloppe le résultat desafeDivide:- Si
safeDivideretourne une erreur, l'envelopper avec :"calculation failed in [calculator_name]: %w" - En cas de succès, retourner le résultat et nil
- Si
- Appeler
performCalculationet gérer le résultat :- Si aucune erreur : afficher
"Calculation successful: [result_formatted_to_precision_decimal_places]" - Si une erreur existe : afficher
"Calculation failed: [error_message]"
- Si aucune erreur : afficher
- Utiliser
errors.Aspour vérifier les types d'erreurs spécifiques dans l'erreur enveloppée :- Afficher
"Checking for division error: [true/false]" - Afficher
"Checking for validation error: [true/false]"
- Afficher
- Si une
DivisionErrorest trouvée, afficher ses détails :"Division Error Details:""Dividend: [dividend]""Divisor: [divisor]"
- Si une
ValidationErrorest trouvée, afficher ses détails :"Validation Error Details:""Field: [field]""Value: [value]"
- Afficher un résumé final :
"Calculator Summary:""Name: [calculator_name]""Mode: [mode]""Operation: [operation]""Input: [num1] [operation_symbol] [num2]"où operation_symbol est "/" pour la division"Precision: [precision] decimal places""Status: [Success/Failed]"
Utilisez le package strings pour diviser les chaînes d'entrée sur les virgules, le package strconv pour convertir les chaînes en nombres, le package errors pour errors.As, et le package fmt pour l'emballage et le formatage des erreurs. Ce défi démontre comment les types d'erreurs personnalisés, l'emballage d'erreurs et la vérification appropriée des erreurs fonctionnent ensemble pour créer des systèmes de gestion d'erreurs robustes qui fournissent des informations détaillées sur différents types d'échecs.
Essayez vous-même
package main
import (
"errors"
"fmt"
"strconv"
"strings"
)
func main() {
// Lire l'entrée
var operationInput string
var settingsInput string
fmt.Scanln(&operationInput)
fmt.Scanln(&settingsInput)
// Analyser l'entrée de l'opération (operation,num1,num2,precision)
operationParts := strings.Split(operationInput, ",")
operation := operationParts[0]
num1, _ := strconv.ParseFloat(operationParts[1], 64)
num2, _ := strconv.ParseFloat(operationParts[2], 64)
precision, _ := strconv.Atoi(operationParts[3])
// Analyser l'entrée des paramètres (calculator_name,mode)
settingsParts := strings.Split(settingsInput, ",")
calculatorName := settingsParts[0]
mode := settingsParts[1]
// TODO: Écrivez votre code ci-dessous
// 1. Créer les structures DivisionError et ValidationError avec les méthodes Error()
// 2. Implémenter la fonction safeDivide
// 3. Implémenter la fonction performCalculation
// 4. Appeler performCalculation et gérer les résultats
// 5. Utiliser errors.As pour vérifier les types d'erreurs spécifiques
// 6. Afficher les détails de l'erreur si elle est trouvée
// 7. Afficher le résumé final
}Toutes les leçons de Logique & Flux
1Structures de contrôle avancées
Switch avec `fallthrough`Sortir de boucles imbriquéesContinuer une boucle spécifiqueL'instruction `goto`Récapitulatif - Contrôle de boucle avancé4Projet : Liste de tâches simple
Configuration du projetAjouter une tâche7Gestion des erreurs en profondeur
Types d'erreurs personnalisésEnvelopper des erreurs avec `%w`Désenvelopper avec `errors.Is`Désenvelopper avec `errors.As`Comprendre `panic`Utiliser `recover`Récapitulatif - Division sécurisée2Structures et Méthodes
Définir des méthodes sur des structuresReceveurs par valeurReceveurs par pointeurChoisir les receveursMéthodes vs FonctionsRécapitulatif - Comportement des structures5Les Maps en profondeur
Maps de StructsPointeurs comme valeurs de MapTester les Maps NilComparer des MapsRécapitulatif - Compteur de fréquence de mots3Interfaces (Les bases)
Qu'est-ce qu'une Interface ?Définir une InterfaceImplémenter une InterfaceUtiliser les types d'InterfaceInterface videAssertions de typeType SwitchRécapitulatif - Formes et comportements