【问题标题】:Use of go's struct pointer as interface使用 go 的 struct 指针作为接口
【发布时间】:2017-04-18 08:00:26
【问题描述】:

我想将 struct 方法作为函数值传递。如果函数需要返回 interface{} 并且它返回 *struct,为什么编译会失败?如果我尝试从声明为返回接口{}(包装函数)的函数返回 *struct,它会完美工作。

package main

func main() {
        println("hello")
        testInterface(wrapper)          // works
        instance := MyStruct{}
        testInterface(instance.works)   // works
        testInterface(instance.fails)   // fails: ./main.go:8: cannot use instance.fails (type func(int) *MyStruct) as type func(int) interface {} in argument to testInterface
}

func testInterface(f func() interface{}) {
        f()
        return
}

type MyStruct struct {
}

func (s *MyStruct) works() interface{} {
        return s
}

func (s *MyStruct) fails() *MyStruct {
        return s
}

func wrapper() interface{} {
        s := MyStruct{}
        return s.fails()

}

【问题讨论】:

    标签: go


    【解决方案1】:

    那是因为它不符合 assignability 标准

    x 可分配给T 类型的变量(“x 可分配给T”)在任何这些情况下:

    • x 的类型与 T 相同。
    • x 的类型 VT 具有相同的底层类型,并且 VT 中的至少一个不是命名类型。
    • T 是一个接口类型,x 实现了T
    • x是双向通道值,T是通道类型,x的类型VT具有相同的元素类型,至少VT中的一个不是命名类型。
    • x 是预声明的标识符 nilT 是指针、函数、切片、映射、通道或接口类型。
    • x 是一个无类型常量,可以用 T 类型的值表示。

    所以,这就解释了为什么testInterface(instance.fails) 失败了:因为instance.fails 不能分配给f func() interface{}

    现在是第二个问题:

    如果我尝试从声明为返回接口{}(包装函数)的函数返回 *struct,它会完美运行。

    它工作正常,因为*struct 类型的值可以分配给interface{} 类型,因为:

    1. 此可分配性规则:“T 是一个接口类型,x 实现了T。”
    2. “一个类型实现了包含其方法的任何子集的任何接口,因此可以实现多个不同的接口。例如,所有类型都实现空接口:”(粗体是我的)

    参考资料:

    【讨论】:

      猜你喜欢
      • 2014-02-16
      • 1970-01-01
      • 2021-10-11
      • 2016-07-17
      • 2020-10-16
      • 2016-07-24
      • 1970-01-01
      • 2014-04-08
      • 2019-07-07
      相关资源
      最近更新 更多