fmt.Println调用Error而不是String()

时间:2017-04-14 15:01:31

标签: go

我有这段代码

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&lt; nil&gt;   不能Sqrt负数:-2不能Sqrt负数:-2

当我为ErrNegativeSqrt实现Stringer接口时,为什么fmt.Println调用Error()方法而不是String()方法?

我是新手,所以我可能会遗漏一些非常明显的东西。

1 个答案:

答案 0 :(得分:9)

documentation states how the value is converted to a string

  
      
  1. 如果操作数实现了错误接口,则将调用Error方法将对象转换为字符串,然后根据动词的需要对其进行格式化(如果有的话)。

  2.   
  3. 如果操作数实现方法String()字符串,则将调用该方法将对象转换为字符串,然后根据动词的需要对其进行格式化(如果有)。

  4.   

error接口位于Stringer之前。

编写函数的更惯用的方法是:

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