在下面的代码中,类型ErrNegativeSqrt
实现了Stringer
和error
接口。由于在Sqrt
方法中返回类型为fmt.Stringer
,我将执行结果除外:
0 nil
0 Impl Stringer type
但实际结果如下,为什么?
0 nil
0 Impl错误类型
package main
import (
"fmt"
)
type ErrNegativeSqrt float64
func Sqrt(x ErrNegativeSqrt) (float64, fmt.Stringer) {
if x < 0 {
return 0, ErrNegativeSqrt(x)
}
return 0, nil
}
func (e ErrNegativeSqrt) String() string {
return "Impl Stringer type"
}
func (e ErrNegativeSqrt) Error() string {
return "Impl error type"
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
答案 0 :(得分:5)
documentation for Package fmt
表示:
...特殊格式 注意事项适用于实现某些接口的操作数。 按申请顺序:
...
- 如果%v动词与#flag(%#v)一起使用,并且操作数实现了GoStringer接口,那么将调用它。
醇>如果格式(对于Println等隐式为%v)对a有效 字符串(%s%q%v%x%X),适用以下两个规则:
如果操作数实现了错误接口,则将调用Error方法...
- 醇>
如果操作数实现方法String()字符串,则将调用该方法...
由于您使用的是fmt.Println
,因此规则4和5会发挥作用,而Error()
优先于String()
答案 1 :(得分:3)
您通过将结果值作为fmt.Stringer
传递给fmt.Println
,忽略了您的函数返回interface{}
的事实。
您只能看到Error()
方法的结果,因为fmt
包在检查error
接口之前会检查fmt.Stringer
接口。