Go Exercise: Errors

interfaceあたりから難しくって脳汁でまくってます。ぼくしです。今回はエラーのところをまとめます。と言ってもinterfaceの扱いの延長なのでinterfaceの理解を深めるってところですね。
ちなみにgo playgroundで一通り触ってnoteにまとめようとしたタイミングでいきなりMacが落ちてびっくりしました。もうそろそろ5年目になるので寿命がきているのでしょうか?

復習:Stringer

復習になりますが、fmtというパッケージにはStringerというインターフェースが用意されています。Stringerインターフェースは文字列を返すString()メソッドを持つことを保証しています。fmt.Printlnなどで出力するときはString()メソッドから返された文字列を出力することになります。
そして自分が定義した型に対してString()メソッドを定義することで出力を任意に指定することが出来ます。

例えば、Passwordの文字列をクライアントサイドであれ、バックエンドサイドであれそのまま表示してしまうのは好ましくありません。そんな時に以下のようにPassword型を定義しString()メソッドを以下のようにします。パスワードの文字列はこの型で扱ってあげれば、出力しても全て*で置き換えられます。間違って表示してしまうミスは起こりません(もちろん他にも実装すべきところはあるでしょうが)。

package main
import (
	"fmt"
)
type Password string
func (p Password) String() string {
	var st string
	for i := 0; i < len(p); i++ {
		st += "*"
	}
	return st
}
func main() {
	var pass Password = "stringggggggg"
	fmt.Println(pass)
}
// 実行結果
*************

Error

Goにはerror型があり、interfaceによってError()メソッドを持つことが保証されいます。Error()メソッドはエラーの際に表示するメッセージを返します。このメソッドを記述することで任意の型に対して任意のエラ〜メッセージを定義することが出来ます。例えば正の値の足し算をする関数に対して負の値が入ればエラーを返すようにします。NegativeNumberErrorという構造体にwhen(エラーが起きた時間), what(エラーメッセージ)を持たせます。

その構造体にError()メソッドを定義してエラーが起きた際のメッセージを返すようにします。正の足し算を行うPositiveAdd()で期待していない値(負の値)が入力された時err変数にエラーメッセージをNegativeNumberErrorから返すようにします。PositiveAdd()自体は計算結果とerr変数(エラーメッセージ)を返すようになっています。
これでエラーの有無によって処理を分けることが出来ます。

package main
import (
	"fmt"
	"time"
)
type NegativeNumberError struct {
	when time.Time
	what string
}
func (e *NegativeNumberError) Error() string {
	return fmt.Sprintf("%s\nat: %v ", e.what, e.when)
}
func PositiveAdd(a, b int) (int, error) {
	var add int = 0
	var err error = nil
	if a > 0 && b > 0 {
		add = a + b
	} else {
		err = &NegativeNumberError{
			time.Now(),
			"Negative number is include.",
		}
	}
	return add, err
}
func main() {
	c, err := PositiveAdd(-1, -1)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(c)
	}
}

正の値の足し算

JavaScriptのようなリッチな言語を使っているとものすごくめんど臭く感じますね。逆に言うとJavaScriptなどはそこらへんの処理をラップして記述しやすい形に整形してくれているのでとてもありがたいですね。

自分で実行してみたい方は以下で試して見てください。

exerciseの問題

package main
import (
	"fmt"
)
type ErrNegativeSqrt float64
func (e ErrNegativeSqrt) Error() string {
	
}
func Sqrt(x float64) (float64, error) {
	z := 1.0
	for i := 1; i < 10; i++ {
		z -= (z*z - x) / (2 * z)
	}
	return z, nil
}
func main() {
	fmt.Println(Sqrt(-2))
}

さて上のコードは平方根を求める関数を定義しています。負の値-nを受け取った時はcannot Sqrt negative number: -nと言うエラーメッセージを表示したいのですが、見ての通り今のままだと不十分です。書き換えて正しく動作するようにしてください。

以下は私の解答です。あってるのかな?


この記事が気に入ったらサポートをしてみませんか?