为什么方法签名必须与接口方法完美匹配

时间:2016-05-28 23:27:25

标签: go

我开始学习Go并且无法理解以下内容:

package main

import "fmt"

type I interface {
    foo(interface {})
}

type S struct {}

func (s S) foo(i int) {
    fmt.Println(i)
}

func main() {
    var i I = S{}
    i.foo(2)
}

这失败了:

cannot use S literal (type S) as type I in assignment:
        S does not implement I (wrong type for foo method)
                have foo(int)
                want foo(interface {})

鉴于foo(int)实施int这一事实,我不明白为什么Go不接受interface {}签名。任何人都可以帮忙解释一下吗?

2 个答案:

答案 0 :(得分:11)

我认为你对界面的理解并不合理。 Interface {}本身就是一种类型。它由两部分组成:基础类型和基础价值。

Golang没有超载。 Golang类型系统按名称匹配,并且要求类型一致

因此,当您定义一个以接口类型作为参数的函数时:

foo(interface {})

这是一个与采用int类型的函数不同的函数:

foo(int)

因此,您应将以下行更改为

func (s S) foo(i interface{}) {
    fmt.Println(i)
}

或者更好的是:

type I interface {
    foo()
}

type S struct {
    I int
}

func (s S) foo() {
    fmt.Println(s.I)
}

func main() {
    var i I = S{2}
    i.foo()
}

答案 1 :(得分:0)

错误消息本身是不言自明的:

"S does not implement I (wrong type for foo method)" 

因此S类型的S {}不能用于I型变量分配的RHS。

要实现I接口,类型S需要定义具有完全相同签名的foo函数。

要实现所需的功能,可以在S中将空接口用作foo函数的输入参数,并输入断言

    package main

    import "fmt"

    type I interface {
        foo(interface {})
    }

    type S struct {}

    func (s S) foo(i interface{}) {
        if i, ok := i.(int); ok{
        fmt.Println(i)
        }
    }

    func main() {
        var i I = S{}
        i.foo(2)
        i.foo("2")
    }

在操场上尝试it