我有一个处理资源解析的系统(将名称与文件路径匹配等)。它解析文件列表,然后保持指向返回接口实现实例的函数的指针。
更容易展示。
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
。
答案 0 :(得分:5)
是的,DDSTexture
完全实施resource.Texture
。
但是命名类型NewDDSTexture (type func(string) *DDSTexture)
与未命名类型func (string) *resource.Texture
不同:他们的 type identity 不匹配:
如果两个函数类型具有相同数量的参数和结果值,相应的参数和结果类型相同,并且两个函数都是可变参数或两者都不是,则它们是相同的。参数和结果名称不需要匹配。
命名和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`
此处,结果值类型与DDSTexture
与resource.Texture
不匹配:
即使一个人实现了另一个人的界面,他们的underlying type仍然不同):你不能assign一个到另一个。
你需要NewDDSTexture()
返回Texture
(没有指针,因为它是一个接口)。
func NewDDSTexture(filename string) Texture
请参阅this example。
正如我在“Cast a struct pointer to interface pointer in golang”中所解释的那样,您通常不需要指向接口的指针。