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

huangapple go评论71阅读模式
英文:

fmt.Println calling Error instead of String()

问题

我有这段代码

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))
}

这段代码的输出是

Cannot Sqrt negative number: 1.4142135623730951
Cannot Sqrt negative number: -2 Cannot Sqrt negative number: -2

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

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

英文:

I have this code

package main

import (
	&quot;fmt&quot;
	&quot;math&quot;
)

type ErrNegativeSqrt float64

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

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

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

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

And the output of this code is

> Cannot Sqrt negative number: 1.4142135623730951 &lt;nil&gt;
> Cannot Sqrt negative number: -2 Cannot Sqrt negative number: -2

When I have implemented the Stringer interface for the ErrNegativeSqrt, why is the fmt.Println invoking the Error() method instead of the String() method?

I am new to go, so I might be missing something very obvious.

答案1

得分: 9

文档说明如何将值转换为字符串

> 4. 如果操作数实现了 error 接口,将调用 Error 方法将对象转换为字符串,然后按照所需的动词格式化。
>
> 5. 如果操作数实现了方法 String() string,将调用该方法将对象转换为字符串,然后按照所需的动词格式化。

error 接口位于 Stringer 之前。

更符合惯用写法的函数如下:

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

The documentation states how the value is converted to a string:

> 4. If an operand implements the error interface, the Error method will be invoked to convert the object to a string, which will then be formatted as required by the verb (if any).
>
> 5. If an operand implements method String() string, that method will be invoked to convert the object to a string, which will then be formatted as required by the verb (if any).

The error interface comes before Stringer.

A more idiomatic way to write the function is:

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

huangapple
  • 本文由 发表于 2017年4月14日 23:01:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/43414130.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定