2017-04-14 1 views
2

私はこのコードfmt.Println()

package main 

import (
    "fmt" 
    "math" 
) 

type ErrNegativeSqrt float64 

func (s ErrNegativeSqrt) String() string { 
    return fmt.Sprintf("%f", float64(s)) 
} 

func (e ErrNegativeSqrt) Error() string { 
    return fmt.Sprintf("Cannot Sqrt negative number: %v", float64(e)) 
} 

func Sqrt(x float64) (ErrNegativeSqrt, error) { 
    if x < 0 { 
     e := ErrNegativeSqrt(x) 
     return e, e 
    } else { 
     return ErrNegativeSqrt(math.Sqrt(x)), nil 
    } 
} 

func main() { 
    fmt.Println(Sqrt(2)) 
    fmt.Println(Sqrt(-2)) 
} 

を持っており、このコードの出力は

では、負の数をSQRTできません:1.4142135623730951 <ゼロ> は負SQRTはできません。番号:-2負の数には対応できません:-2

私はStringer inte ErrNegativeSqrtのrfaceについて、なぜfmt.PrintlnがString()メソッドの代わりにError()メソッドを呼び出すのですか?

私は新しいですので、私は非常に明白な何かを逃しているかもしれません。

答えて

6

documentation states how the value is converted to a string

  • オペランドがエラーインタフェースを実装している場合、エラー方法は、次いで、フォーマットされた文字列にオブジェクトを変換するために呼び出されます動詞の必要に応じて(もしあれば)。

  • オペランドがメソッドString()の文字列を実装する場合、そのメソッドはオブジェクトを文字列に変換するために呼び出され、そのオブジェクトは動詞(必要な場合)の必要に応じてフォーマットされます。

  • errorインタフェースはStringerの前に来ます。

    は、関数を記述するために、より慣用的な方法は次のとおりです。

    func Sqrt(x float64) (float64, error) { 
        if x < 0 { 
        return 0, ErrNegativeSqrt(x) 
        } 
        return math.Sqrt(x), nil 
    } 
    
    +0

    他の方法は、それが通常の文字列の代わりに、エラーメッセージを表示させるには? – Srisa

    +0

    @Srisa: 'fmt.Println(Sqrt(2).String())'? – Flimzy

    +3

    2引数の戻り値なので、うまくいきません。しかし、率直に言って、それは一般的に問題のあるデザインを反映しています。関数は複数の値を返すことができるので、エラー項目を返すだけでエラー項目を実装する本当の理由はありません(実際には同じ項目を2回戻すことでエラーを返すことができます)。悪いコードのにおいが問題です。 – Kaedys

    関連する問題