2016-05-17 5 views
1

は、このプログラムは次のエラーでコンパイルに失敗し関数は、関数型の正確な署名を満たす必要がありますか?

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"}) 
} 

次のような単純な囲碁プログラムを考えてみましょう:

./main.go:21: cannot use json.NewEncoder (type func(io.Writer) *json.Encoder) as type MyEncoderCreator in field value 

これはなぜでしょうか? json.Encoder構造体には、MyEncoderインターフェイスを満たすレシーバがあります。したがってjson.NewEncoder機能をMyContainer.Creatorに割り当てることができますか?

答えて

2

はい、関数は、関数型の正確な署名を満たす必要があります。他のコンテキストでも同様のことが起こります。それは一般的にはtypes in Go lack covarianceと言うより正式な方法です。ここでは、json.NewEncoderMyEncoderを返す関数にラップすることができます。あなたは、一般的に、その後のポインタに内部インターフェイス値を格納する場合、単にコピーを避けるために、インタフェース値にあなたはまた、ポインタを必要としないので、

私は値型MyEncoderないポインタ*MyEncoderを使うだろう。それが役に立ったらhere's more on pointers vs. values

関連する問題