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

kas*_*sky 8 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)
}
Run Code Online (Sandbox Code Playgroud)

这失败了:

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 {})
Run Code Online (Sandbox Code Playgroud)

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

khr*_*hrm 11

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

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

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

foo(interface {})
Run Code Online (Sandbox Code Playgroud)

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

foo(int)
Run Code Online (Sandbox Code Playgroud)

所以你应该改变以下行

func (s S) foo(i interface{}) {
    fmt.Println(i)
}
Run Code Online (Sandbox Code Playgroud)

或者更好的是:

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()
}
Run Code Online (Sandbox Code Playgroud)