カスタムエラー

チュートリアルのゴーシリーズ - 31カスタムエラー

新しい機能を使用して、カスタムエラーを作成します。

カスタムエラーの最も簡単な方法を作成すると、使用することですerrorsパッケージのNew機能を。

新しい使用で機能をでカスタムエラーを作成する前に、私たちは見てみNew達成する方法です。、以下に示すようにerrorsパッケージNew機能の実装。

// Package errors implements functions to manipulate errors.
package errors

// New returns an error that formats as the given text.
func New(text string) error {
    return &errorString{text}
}

// errorString is a trivial implementation of error.
type errorString struct {
    s string
}

func (e *errorString) Error() string {
    return e.s
}

New機能の実装は非常に簡単です。errorStringある構造のみ1つの文字列フィールドがあり、タイプsライン14は、使用しerrorString実装するために、受信者(ポインタ受信機)へのポインタをerrorインターフェースError() string 方法を

5行目Newの関数は、作成するには、このパラメータの文字列パラメータを持つerrorString型の変数を、そのアドレスを返します。だから、作成され、新しいエラーを返します。

今、私たちはすでに知っているNew機能がどのように機能するかを、私たちは、プログラムで使用し始めたNewカスタムエラーバーを作成します。

私たちは、半径が負の場合、それはエラーを返します、円の半径を計算するための簡単なプログラムを作成します。

package main

import ( 
    "errors"
    "fmt"
    "math"
)

func circleArea(radius float64) (float64, error) { 
    if radius < 0 {
        return 0, errors.New("Area calculation failed, radius is less than zero")
    }
    return math.Pi * radius * radius, nil
}

func main() { 
    radius := -20.0
    area, err := circleArea(radius)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("Area of circle %0.2f", area)
}

glayground上で実行されています

半径がゼロ未満(ライン10)である場合、上記の手順で、我々は確認してください。半径がゼロ未満である場合、我々は、0に等しい面積に戻り、対応するエラーメッセージが表示されます。半径がゼロより大きい場合、それは面積を計算し、戻り値であろうnilエラー(線13)の。

ではmain機能、私たちはライン19上のエラーをチェックすることは同じですnilそうでない場合nil、我々はそうでない場合、我々は円形の領域が印刷されます、エラーをプリントアウトし、それを返します。

私たちのプログラムでは、半径はそれほどプリントアウトし、ゼロ未満です:

Area calculation failed, radius is less than zero

使用Errorfはエラーに多くの情報を追加します

上記のプログラムではうまく動作しますが、我々はあまり良く、円の現在の半径をプリントアウトすることができます。この使用はするfmtパッケージErrorfの機能を。Errorf書式指定機能、所定のフォーマットエラー、戻り誤差が満たしている文字列

次に、我々は使用Errorf我々のプログラムを改善するための機能を。

package main

import ( 
    "fmt"
    "math"
)

func circleArea(radius float64) (float64, error) { 
    if radius < 0 {
        return 0, fmt.Errorf("Area calculation failed, radius %0.2f is less than zero", radius)
    }
    return math.Pi * radius * radius, nil
}

func main() { 
    radius := -20.0
    area, err := circleArea(radius)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("Area of circle %0.2f", area)
}

遊び場で実行されています

上記の手順では、我々が使用するErrorf(ライン10)印刷半径エラーが発生しました。プログラム意志の出力を実行します:

Area calculation failed, radius -20.00 is less than zero

構造の使用方法の詳細については、エラー・フィールドを提供

エラーは、達成するために使用することができるerror インターフェース構造を表現します。この方法では、我々はより柔軟にエラーを処理することができます。上記の例では、私たちがアクセスしたい場合は、エラーの半径を引き起こし、そして今、唯一の方法は、エラーメッセージの説明を解析することですArea calculation failed, radius -20.00 is less than zero情報の変更を説明した後、プログラムが間違って行きますので、そうすることは、非常に良いではありません。

我々は、この方法は、構造体フィールドが原因のアクセスに使用することができますについて説明し、このセクションのチュートリアルでは、「より多くの情報フィールドのための構造を使用し、基本的な構造タイプをアサート」、使用される標準ライブラリを使用します誤差半径。私たちは、実装が作成されますerrorインターフェイスのボディタイプの構造を、そしてエラーに関する詳細な情報を提供するために、フィールドでそれを使用します。

最初のステップは、構造タイプがエラーを示して作成することです。命名規則の間違った種類はに名前でError終わり。だから我々は、同様の名前の構造式を置くかもしれませんareaError

type areaError struct { 
    err    string
    radius float64
}

上記構造は、型有しradiusエラーに関連する半径を格納するフィールドを、errフィールドは、実際のエラーメッセージを格納します。

次のステップは、実装するerrorインターフェイスを。

func (e *areaError) Error() string { 
    return fmt.Sprintf("radius %0.2f: %s", e.radius, e.err)
}

上記のコードでは、我々は、ポインタ受信機を使用し*areaError、実装するerrorインターフェースError() string方法を。そして方法アウトプリントがエラーの半径に関して説明しました。

レッツ・書き込みmain機能およびcircleArea機能は、プログラム全体を完成させます。

package main

import ( 
    "fmt"
    "math"
)

type areaError struct { 
    err    string
    radius float64
}

func (e *areaError) Error() string { 
    return fmt.Sprintf("radius %0.2f: %s", e.radius, e.err)
}

func circleArea(radius float64) (float64, error) { 
    if radius < 0 {
        return 0, &areaError{"radius is negative", radius}
    }
    return math.Pi * radius * radius, nil
}

func main() { 
    radius := -20.0
    area, err := circleArea(radius)
    if err != nil {
        if err, ok := err.(*areaError); ok {
            fmt.Printf("Radius %0.2f is less than zero", err.radius)
            return
        }
        fmt.Println(err)
        return
    }
    fmt.Printf("Area of rectangle1 %0.2f", area)
}

遊び場で実行されています

上記手順において、circleArea円の面積を算出する(ライン17)。半径が、ゼロ未満である、それはエラーメッセージと対応する誤差半径を通過し、ゼロ以上である生成する関数を最初にチェックareaError値型を、戻りareaError同時にアドレス値はareaゼロに(ライン19)が等しいです。我々は、エラー情報(すなわち、誤差半径を引き起こした)を提供ので、我々はそれに定義された構造のカスタム・エラー・フィールドを使用します

半径が負でない場合、関数計算と戻りライン21内のエリア、及び誤り値nil

main関数の26行、我々は、半径20の円の面積を計算することを試みます。半径がゼロ未満であるため、このようにエラーの原因となります。

私たちは、エラーかどうかのライン27上で確認nilし、次の行のことを主張する*areaErrorタイプ。エラーがある場合は\*areaError種類が、我々はそれを使用することができerr.radius、プリントアウト誤差半径(ライン29)、カスタムエラーメッセージを取得するために、そして最終的にプログラムを終了するに戻ります

アサーションが間違っている場合、我々は最初の行32の印刷エラーとリターンです。エラーが発生しない場合は、ライン35は、面積が印刷されます。

プログラムが出力されます:

Radius -20.00 is less than zero

前回のチュートリアルが言及しましょう使用第二の方法を、カスタムエラータイプのメソッドを使用しての詳細については間違っを提供しています。

エラーを提供する方法を用いた構造の種類の詳細について

ここでは、長方形の面積を計算するプログラムを書きます。ゼロ未満の長さまたは幅場合、プログラムはエラーを出力します。

最初のステップは、偽の表現構造を作成することです。

type areaError struct { 
    err    string //error description
    length float64 //length which caused the error
    width  float64 //width which caused the error
}

エラーの説明に加えて、構造タイプフィールド上、間違った幅と高さにつながる可能性があります。

今、私たちが間違った型を持っていることを、我々は、実装する必要がありerror、それはより多くのエラーメッセージを提供し、インターフェースを、エラーの種類は、2つのメソッドを追加します。

func (e *areaError) Error() string { 
    return e.err
}

func (e *areaError) lengthNegative() bool { 
    return e.length < 0
}

func (e *areaError) widthNegative() bool { 
    return e.width < 0
}

上記のコードフラグメントにError() stringエラー処理の説明に戻ります。場合lengthゼロ未満、lengthNegative() boolメソッド戻りtrue、そして場合widthよりも小さいゼロ、widthNegative() boolメソッドが戻りますtrue両方の方法は、エラーの詳細を提供し、それは理由を促す場合、我々は(負の数の長さ又は幅であるネガティブ)面積を計算することができませんでした。だから我々は、より多くのエラーメッセージを提供するために、間違ったタイプの構造方法の二人は、持っています

次のステップは、面積を計算するための関数を記述することです。

func rectArea(length, width float64) (float64, error) { 
    err := ""
    if length < 0 {
        err += "length is less than zero"
    }
    if width < 0 {
        if err == "" {
            err = "width is less than zero"
        } else {
            err += ", width is less than zero"
        }
    }
    if err != "" {
        return 0, &areaError{err, length, width}
    }
    return length * width, nil
}

上記rectAreaゼロより小さい場合は、長さ又は幅は、ゼロ以上である機能をチェックし、rectAreaそれ以外の場合は、エラーメッセージを返しrectAreaた矩形の面積の値を返しnil、エラーを。

さんが作成してみましょうmain全体のプログラムを完了するための機能を。

func main() { 
    length, width := -5.0, -9.0
    area, err := rectArea(length, width)
    if err != nil {
        if err, ok := err.(*areaError); ok {
            if err.lengthNegative() {
                fmt.Printf("error: length %0.2f is less than zero\n", err.length)

            }
            if err.widthNegative() {
                fmt.Printf("error: width %0.2f is less than zero\n", err.width)

            }
            return
        }
        fmt.Println(err)
        return
    }
    fmt.Println("area of rect", area)
}

mainプロセス、我々は、エラーがあるかどうかを調べたnil(ライン4)。値がエラーでない場合はnil、我々は次の行のアサーションます*areaErrorタイプ。その後、我々は、使用lengthNegative()およびwidthNegative()方法、幅の長さは少ないため、ゼロ以下ゼロよりエラーをチェック。我々はより多くのエラーメッセージを提供するために、構造方法の間違った種類を使用しているので。

エラーが発生していない場合、それは長方形の面積を出力します。

ここにあなたの参考のために全体のプログラムのためのコードです。

package main

import "fmt"

type areaError struct { 
    err    string  //error description
    length float64 //length which caused the error
    width  float64 //width which caused the error
}

func (e *areaError) Error() string { 
    return e.err
}

func (e *areaError) lengthNegative() bool { 
    return e.length < 0
}

func (e *areaError) widthNegative() bool { 
    return e.width < 0
}

func rectArea(length, width float64) (float64, error) { 
    err := ""
    if length < 0 {
        err += "length is less than zero"
    }
    if width < 0 {
        if err == "" {
            err = "width is less than zero"
        } else {
            err += ", width is less than zero"
        }
    }
    if err != "" {
        return 0, &areaError{err, length, width}
    }
    return length * width, nil
}

func main() { 
    length, width := -5.0, -9.0
    area, err := rectArea(length, width)
    if err != nil {
        if err, ok := err.(*areaError); ok {
            if err.lengthNegative() {
                fmt.Printf("error: length %0.2f is less than zero\n", err.length)

            }
            if err.widthNegative() {
                fmt.Printf("error: width %0.2f is less than zero\n", err.width)

            }
            return
        }
        fmt.Println(err)
        return
    }
    fmt.Println("area of rect", area)
}

遊び場で実行されています

プログラムがプリントアウトされます:

error: length -5.00 is less than zero 
error: width -9.00 is less than zero

前のチュートリアルでは、エラー処理、我々は今、2つの例を見てきましたエラーに関する詳細な情報を提供する3つの方法をご紹介します。

第三の方法は、比較的単純で直接的な比較を使用します。私はあなたが定義間違っからより多くの情報を与えるために、このメソッドを使用しようとすることができ、練習として残しました。

このチュートリアルでは、以上です。

このチュートリアルの内容の概要:

  • 使用するNewカスタムエラーを作成する機能を
  • 使用するErrorより多くのエラーメッセージを追加します
  • エラーに関する詳細な情報を提供するために、構造およびフィールドを使用
  • エラー情報を提供するための構造及び方法を用いて

私はあなたが幸せにしたいです。





おすすめ

転載: www.cnblogs.com/hualou/p/12069838.html