まとめ:安全な除算
CoddyのGOジャーニー「論理とフロー」セクションの一部 — レッスン 44/68。
チャレンジ
簡単複数のカスタムエラー型と適切なエラーハンドリングを実装した、安全な除算を行う包括的な計算機を構築してください。このチャレンジでは、カスタムエラー型、エラーラッピング、およびエラーチェックを組み合わせて、さまざまな計算操作の失敗を適切に処理する堅牢なシステムを作成します。
2つの入力を受け取ります:
"operation,num1,num2,precision"形式の操作詳細を含む文字列(例:"divide,10,0,2")"calculator_name,mode"形式の計算機設定を含む文字列(例:"ScientificCalc,strict")
あなたのタスクは以下の通りです:
- 2つのカスタムエラー型を作成します:
Dividend(float64) とDivisor(float64) フィールドを持つDivisionError構造体Field(string) とValue(float64) フィールドを持つValidationError構造体
DivisionErrorに対して、"division error: cannot divide [dividend] by [divisor]"を返すError() stringメソッドを実装します。ValidationErrorに対して、"validation error: invalid [field] value [value]"を返すError() stringメソッドを実装します。- 最初の入力をカンマで分割して、operation、num1、num2、および precision を取得します。
- 2番目の入力をカンマで分割して、calculator name と mode を取得します。
- 文字列の数値を float64 に、precision を int に変換します。
- 2つの float64 パラメータを受け取り、(float64, error) を返す
safeDivide関数を作成します:- divisor が 0 の場合、0 と、dividend および divisor の値を持つ
DivisionErrorを返します。 - dividend が負の値で、mode が
"strict"の場合、0 と、field が"dividend"でその dividend の値を持つValidationErrorを返します。 - divisor が負の値で、mode が
"strict"の場合、0 と、field が"divisor"でその divisor の値を持つValidationErrorを返します。 - それ以外の場合は、除算結果と nil を返します。
- divisor が 0 の場合、0 と、dividend および divisor の値を持つ
safeDivideの結果をラップするperformCalculation関数を作成します:safeDivideがエラーを返した場合、それを"calculation failed in [calculator_name]: %w"でラップします。- 成功した場合は、結果と nil を返します。
performCalculationを呼び出し、結果を処理します:- エラーがない場合:
"Calculation successful: [result_formatted_to_precision_decimal_places]"を出力します。 - エラーがある場合:
"Calculation failed: [error_message]"を出力します。
- エラーがない場合:
errors.Asを使用して、ラップされたエラー内の特定の型をチェックします:"Checking for division error: [true/false]"を出力します。"Checking for validation error: [true/false]"を出力します。
DivisionErrorが見つかった場合、その詳細を出力します:"Division Error Details:""Dividend: [dividend]""Divisor: [divisor]"
ValidationErrorが見つかった場合、その詳細を出力します:"Validation Error Details:""Field: [field]""Value: [value]"
- 最終的なサマリーを表示します:
"Calculator Summary:""Name: [calculator_name]""Mode: [mode]""Operation: [operation]""Input: [num1] [operation_symbol] [num2]"(ここで operation_symbol は除算の場合 "/" とします)"Precision: [precision] decimal places""Status: [Success/Failed]"
入力文字列をカンマで分割するには strings パッケージを、文字列を数値に変換するには strconv パッケージを、errors.As には errors パッケージを、エラーのラッピングとフォーマットには fmt パッケージを使用してください。このチャレンジは、カスタムエラー型、エラーラッピング、および適切なエラーチェックがどのように連携して、さまざまな種類の失敗に関する詳細な情報を提供する堅牢なエラーハンドリングシステムを構築するかを示しています。
自分で試してみよう
package main
import (
"errors"
"fmt"
"strconv"
"strings"
)
func main() {
// 入力を読み込む
var operationInput string
var settingsInput string
fmt.Scanln(&operationInput)
fmt.Scanln(&settingsInput)
// 演算の入力を解析する (演算,数値1,数値2,精度)
operationParts := strings.Split(operationInput, ",")
operation := operationParts[0]
num1, _ := strconv.ParseFloat(operationParts[1], 64)
num2, _ := strconv.ParseFloat(operationParts[2], 64)
precision, _ := strconv.Atoi(operationParts[3])
// 設定の入力を解析する (電卓名,モード)
settingsParts := strings.Split(settingsInput, ",")
calculatorName := settingsParts[0]
mode := settingsParts[1]
// TODO: 以下にコードを記述してください
// 1. Error() メソッドを持つ DivisionError と ValidationError 構造体を作成する
// 2. safeDivide 関数を実装する
// 3. performCalculation 関数を実装する
// 4. performCalculation を呼び出し、結果を処理する
// 5. errors.As を使用して特定の型のエラーを確認する
// 6. エラーが見つかった場合は詳細を出力する
// 7. 最終的な要約を表示する
}論理とフローのすべてのレッスン
7エラーハンドリング詳説
カスタムエラー型%w によるエラーのラッピングerrors.Is によるアンラップerrors.As によるアンラップpanic の理解recover の使用まとめ:安全な除算