Consider the following simple go program
package main
import (
"io"
"encoding/json"
"os"
)
type MyEncoder interface {
Encode(v interface{}) error
}
type MyEncoderCreator func(io.Writer) *MyEncoder
type MyContainer struct {
Creator MyEncoderCreator
}
func main() {
container := Container{
Creator:json.NewEncoder,
}
encoder := container.Creator(os.Stdout)
encoder.Encode(map[string]string{"key":"value"})
}
This program fails to compile with the following error:
./main.go:21: cannot use json.NewEncoder (type func(io.Writer) *json.Encoder) as type MyEncoderCreator in field value
Why is this? The json.Encoder
struct has a receiver that satisfies the MyEncoder
interface. So should the json.NewEncoder
function be allowed to assigned to MyContainer.Creator
?
Yes, a function has to satisfy the exact signature of the function type. Similar things come up in other contexts: a more formal way to say it is that generally types in Go lack covariance. Here, you could wrap json.NewEncoder
in a function returning MyEncoder
.
I'd use the value type MyEncoder
not the pointer *MyEncoder
because if you store a pointer inside the interface value then generally you don't also need a pointer to the interface value just to avoid copies; here's more on pointers vs. values if it helps.