【问题标题】:Go: function callback returning implementation of interfaceGo:函数回调返回接口的实现
【发布时间】:2015-02-05 19:44:23
【问题描述】:

我有一个处理资源解析的系统(将名称与文件路径匹配等)。它解析文件列表,然后保存指向返回接口实现实例的函数的指针。

更容易展示。

resource.go

package resource

var (
    tex_types    map[string]func(string) *Texture = make(map[string]func(string) *Texture)
    shader_types map[string]func(string) *Shader  = make(map[string]func(string) *Shader)
)

type Texture interface {
    Texture() (uint32, error)
    Width() int
    Height() int
}

func AddTextureLoader(ext string, fn func(string) *Texture) {
    tex_types[ext] = fn
}

dds.go

package texture

type DDSTexture struct {
    path   string
    _tid   uint32
    height uint32
    width  uint32
}

func NewDDSTexture(filename string) *DDSTexture {
    return &DDSTexture{
        path:   filename,
        _tid:   0,
        height: 0,
        width:  0,
    }
}


func init() {
    resource.AddTextureLoader("dds", NewDDSTexture)
}

DDSTexture 完全实现了Texture 接口,我只是省略了这些函数,因为它们很大,不是我的问题的一部分。

编译这两个包时,出现如下错误:

resource\texture\dds.go:165: cannot use NewDDSTexture (type func(string) *DDSTexture) as type func (string) *resource.Texture in argument to resource.AddTextureLoader

我该如何解决这个问题,或者这是界面系统的错误?重申一下:DDSTexture 完全实现了resource.Texture

【问题讨论】:

    标签: interface go callback return-value return-type


    【解决方案1】:

    是的,DDSTexture 完全实现了resource.Texture

    但命名类型 NewDDSTexture (type func(string) *DDSTexture) 与未命名类型 func (string) *resource.Texture 不同:它们的 type identity 不匹配:

    如果两个函数类型相同,如果它们具有相同数量的参数和结果值,对应的参数和结果类型相同,并且两个函数都是可变的,或者两者都不是。参数和结果名称不需要匹配。

    named 和 unnamed type 总是不同的。

    即使你为你的函数定义了一个命名类型,它也不起作用:

    type FuncTexture func(string) *Texture
    func AddTextureLoader(ext string, fn FuncTexture)
    
    cannot use NewDDSTexture (type func(string) `*DDSTexture`) 
    as type `FuncTexture` in argument to `AddTextureLoader`
    

    这里,结果值类型不匹配DDSTextureresource.Texture
    即使一个实现了另一个的接口,他们的underlying type仍然不同):你不能@987654324 @ 一对一。

    您需要NewDDSTexture() 返回Texture(没有指针,因为它是一个接口)。

    func NewDDSTexture(filename string) Texture
    

    this example

    正如我在“Cast a struct pointer to interface pointer in golang”中解释的那样,您通常不需要指向接口的指针。

    【讨论】:

    • 我已经尝试让NewDDSTexture() 返回Texture,但结果是:*resource.Texture is pointer to interface, not interface
    • @JesseBrands 对。我已从答案中删除了指针,并添加了指向 stackoverflow.com/a/27178682/6309 的链接,我在其中解释说您通常不需要/使用指向接口的指针。
    • 感谢您的出色回答,解决了我的问题并且现在我明白了。
    猜你喜欢
    • 2019-12-17
    • 2019-12-19
    • 2020-04-07
    • 2021-07-21
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    相关资源
    最近更新 更多