【问题标题】:Confused: implement multiple interfaces in Go困惑:在 Go 中实现多个接口
【发布时间】:2016-05-05 18:46:47
【问题描述】:

在下面的代码中,ErrNegativeSqrt 类型实现了Stringererror 接口。由于在Sqrt 方法中的返回类型是fmt.Stringer,我将除了执行结果之外:

0 无

0 隐式纵梁类型

但实际结果如下,为什么呢?

0 无

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

【问题讨论】:

    标签: go interface


    【解决方案1】:

    documentation for Package fmt 声明:

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

    ...

    1. 如果 %v 动词与 # 标志 (%#v) 一起使用,并且操作数实现了 GoStringer 接口,则会调用该接口。

    如果格式(对于 Println 等隐含 %v)对 string (%s %q %v %x %X),以下两条规则适用:

    1. 如果操作数实现了error接口,则会调用Error方法...

    2. 如果操作数实现方法 String() 字符串,将调用该方法...

    由于您使用的是fmt.Println,规则 4 和 5 开始发挥作用,它更喜欢调用 Error() 而不是 String()

    【讨论】:

      【解决方案2】:

      您忽略了这样一个事实,即您的函数通过将结果值作为interface{} 传递给fmt.Println 来返回fmt.Stringer

      您看到Error() 方法的结果只是因为fmt 包在检查fmt.Stringer 接口之前检查了error 接口。

      【讨论】:

        猜你喜欢
        • 2019-01-07
        • 2011-01-18
        • 2011-06-07
        • 2012-04-10
        • 1970-01-01
        • 2018-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多