Reputation: 2877
I got a system that handles the resolving of resources (matching a name to a file path, etc). It parses a list of files and then keeps pointers to a function that returns an instance of an implementation of an interface.
It's easier to show.
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
fully implements the Texture
interface, I just omitted those functions because they're huge and not part of my question.
When compiling these two packages, the following error arises:
resource\texture\dds.go:165: cannot use NewDDSTexture (type func(string) *DDSTexture) as type func (string) *resource.Texture in argument to resource.AddTextureLoader
How would I resolve this problem, or is this a bug with the interface system? Just reiterating: DDSTexture
fully implements resource.Texture
.
Upvotes: 2
Views: 1119
Reputation: 1323553
Yes, DDSTexture
fully implements resource.Texture
.
But the named type NewDDSTexture (type func(string) *DDSTexture)
isn't the same as the unamed type func (string) *resource.Texture
: their type identity doesn't match:
Two function types are identical if they have the same number of parameters and result values, corresponding parameter and result types are identical, and either both functions are variadic or neither is. Parameter and result names are not required to match.
A named and an unnamed type are always different.
Even if you defined a named type for your function, it wouldn't work:
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`
Here, the result value type don't match DDSTexture
vs. resource.Texture
:
Even if one implements the interface of the other, their underlying type still differ): you cannot assign one to the other.
You need for NewDDSTexture()
to return Texture
(no pointer, since it is an interface).
func NewDDSTexture(filename string) Texture
See this example.
As I explained in "Cast a struct pointer to interface pointer in golang", you usually don't need a pointer to an interface.
Upvotes: 5