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 appropriée des erreurs. Ce défi combine les types d’erreurs personnalisés, l’encapsulation des erreurs et la vérification des erreurs afin de créer un système robuste qui gère correctement 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 :
- La structure
DivisionErroravec les champsDividend(float64) etDivisor(float64) - La structure
ValidationErroravec les champsField(string) etValue(float64)
- La structure
- Implémenter la méthode
Error() stringpourDivisionError, qui renvoie :"division error: cannot divide [dividend] by [divisor]" - Implémenter la méthode
Error() stringpourValidationError, qui renvoie :"validation error: invalid [field] value [value]" - Analyser la première entrée en la divisant sur les virgules pour obtenir l’opération, num1, num2 et precision
- Analyser la deuxième entrée en la divisant sur les virgules pour obtenir le nom de la calculatrice et le mode
- Convertir les nombres sous forme de chaînes en float64 et precision en int
- Créer une fonction
safeDividequi accepte deux paramètres float64 et renvoie (float64, error) :- Si le diviseur vaut 0, renvoyer 0 et une
DivisionErroravec les valeurs du dividende et du diviseur - Si le dividende est négatif et que le mode est
"strict", renvoyer 0 et uneValidationErroravec le champ"dividend"et la valeur du dividende - Si le diviseur est négatif et que le mode est
"strict", renvoyer 0 et uneValidationErroravec le champ"divisor"et la valeur du diviseur - Sinon, renvoyer le résultat de la division et nil
- Si le diviseur vaut 0, renvoyer 0 et une
- Créer une fonction
performCalculationqui encapsule le résultat desafeDivide:- Si
safeDividerenvoie une erreur, l’encapsuler avec :"calculation failed in [calculator_name]: %w" - En cas de réussite, renvoyer le résultat et nil
- Si
- Appeler
performCalculationet gérer le résultat :- En l’absence d’erreur : afficher
"Calculation successful: [result_formatted_to_precision_decimal_places]" - Si une erreur existe : afficher
"Calculation failed: [error_message]"
- En l’absence d’erreur : afficher
- Utiliser
errors.Aspour vérifier les types d’erreurs spécifiques dans l’erreur encapsulé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 vaut "/" pour divide"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’encapsulation et le formatage des erreurs. Ce défi montre comment les types d’erreurs personnalisés, l’encapsulation des erreurs et la vérification appropriée des erreurs fonctionnent ensemble pour créer des systèmes robustes de gestion des erreurs 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 comportementsEntraînez-vous par vous-même : Compilateur Go en ligne