困惑:在Go中实现多个接口

困惑:在Go中实现多个接口,go,interface,Go,Interface,在下面的代码中,类型ErrNegativeSqrt实现了Stringer和error接口。由于在Sqrt方法中,返回类型为fmt.Stringer,因此我希望执行结果为: 0零 0 Impl Stringer类型 但实际结果如下,为什么 0零 0 Impl错误类型 主程序包 进口( “fmt” ) 类型ErrNegativeSqrt float64 职能Sqrt(x ErrNegativeSqrt)(浮动64,格式桁条){ 如果x传递给fmt.Println 只有当fmt包在检查fmt.Stri

在下面的代码中,类型
ErrNegativeSqrt
实现了
Stringer
error
接口。由于在
Sqrt
方法中,返回类型为
fmt.Stringer
,因此我希望执行结果为:

0零

0 Impl Stringer类型

但实际结果如下,为什么

0零

0 Impl错误类型

主程序包
进口(
“fmt”
)
类型ErrNegativeSqrt float64
职能Sqrt(x ErrNegativeSqrt)(浮动64,格式桁条){
如果x<0{
返回0,ErrNegativeSqrt(x)
}
返回0,零
}
func(e ErrNegativeSqrt)String()字符串{
返回“Impl Stringer type”
}
func(e ErrNegativeSqrt)Error()字符串{
返回“Impl错误类型”
}
func main(){
格式打印(Sqrt(2))
格式打印(Sqrt(-2))
}
声明:

。。。特殊格式 注意事项适用于实现某些接口的操作数。 按申请顺序:

  • 如果%v谓词与#标志(%#v)一起使用,并且操作数实现了GoStringer接口,则将调用该接口
  • 如果格式(对于Println等隐式为%v)对 字符串(%s%q%v%x%x),以下两条规则适用:

  • 如果操作数实现错误接口,将调用error方法

  • 如果操作数实现方法String()String,将调用该方法

  • 由于您使用的是
    fmt.Println
    ,因此规则4和5开始起作用,它更倾向于调用
    Error()
    ,而不是
    String()
    以下状态:

    。。。特殊格式 注意事项适用于实现某些接口的操作数。 按申请顺序:

  • 如果%v谓词与#标志(%#v)一起使用,并且操作数实现了GoStringer接口,则将调用该接口
  • 如果格式(对于Println等隐式为%v)对 字符串(%s%q%v%x%x),以下两条规则适用:

  • 如果操作数实现错误接口,将调用error方法

  • 如果操作数实现方法String()String,将调用该方法


  • 由于您使用的是
    fmt.Println
    ,因此规则4和5开始发挥作用,它们更喜欢调用
    Error()
    而不是
    String()
    ,您忽略了一个事实,即您的函数通过将结果值作为
    接口{}
    传递给
    fmt.Println
    ,从而返回
    fmt.Stringer


    您可以看到
    错误()的结果
    方法,因为
    fmt
    包在检查
    fmt.Stringer
    接口之前先检查
    error
    接口。

    您忽略了函数返回
    fmt.Stringer
    的事实,将结果值作为
    接口{code>传递给
    fmt.Println

    只有当
    fmt
    包在检查
    fmt.Stringer
    接口之前先检查
    Error
    接口,才能看到
    Error()
    方法的结果

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