关于golang的接口用法

package main

type SomeMethod interface {
    Get() string
}

type Method struct {
    Data string
}

func (m *Method) Get() string {
    return m.Data
}

func main() {
    var (
        sli []*Method
    )
    m := &Method{}

    sli = append(sli, m)

    BatchGet(sli...) // 不支持
    BatchGet(sli[0], sli[1]) // 支持
}

func BatchGet(ms ...SomeMethod) {
    for _, v := range ms {
        v.Get()
    }
}

在我理解 sli... 应该跟[]slice是不同数据结构吧
为什么两种BatchGet的调用 第一种会不支持呢?

阅读 2.3k
4 个回答

可变参数在golang中传递给函数后,函数会构建一个切片用来储存传递的参数,例如:

names := []string{"carl", "sagan"}
//调用
toFullname(names...)
//内部会重用外部传过来的names,因此函数内的names跟传递的参数底层会共用一个array指针,某些情况下直接赋值会导致影响外部参数

假设你传入了一个已有的切片到某可变参数函数:

dennis := []string{"dennis", "ritchie"}

toFullname(dennis...)

假设这个函数在内部改变了可变参数的第一个元素,譬如这样:

func toFullname(names ...string) string {
  names[0] = "guy"
  return strings.Join(names, " ")
}

//而这个修改会影响到源切片,”dennis“ 现在的值是:
[]string{"guy", "ritchie"}
而非最初:
[]string{"dennis", "ritchie"}

很明显,你的代码中 []*Method 跟 []SomeMethod不是一个类型,所以不支持你这种写法。

可以参考下这篇文章: https://studygolang.com/artic...

cannot use sli (type []*Method) as type []SomeMethod in argument to BatchGet
类型不匹配,将

func BatchGet(ms ...SomeMethod) {

更该为

func BatchGet(ms ...*Method) {

因为[]*Method 跟 []SomeMethod不是一个类型
你只要改成var sli []SomeMethod就可以了

换个说法:

type SomeMethod interface {
    Get() string
}

type Method struct {
    Data string
}

func (m *Method) Get() string {
    return m.Data
}

func main() {
    var (
        sli []*Method
        m = &Method{}
    )
    sli = append(sli, m)

    BatchGet(sli) // 不支持
}

func BatchGet(ms []SomeMethod) {
    for _, v := range ms {
        v.Get()
    }
}

原因和上述代码一致:在Go中并不支持 []type => []interface的转换。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题