変数やメソッドの仮引数としてインターフェース型のスライスを定義しておき、実際には構造体のスライスを渡したいというケースがあります。
これはスライスでなければ上手く動きます。しかし、スライスではエラーになってしまいます。
次のようなコードです。
package main
import "fmt"
type Human interface {
Greet()
}
type PoliceOfficer struct{}
func (po *PoliceOfficer) Greet() {
fmt.Println("Hi")
}
func main() {
var human Human
policeOfficer := &PoliceOfficer{}
human = policeOfficer
human.Greet() // -> "Hi"
var humans []Human
policeOfficers := []*PoliceOfficer{policeOfficer}
humans = policeOfficers // -> cannot use policeOfficers (variable of type []*PoliceOfficer) as type []Human in assignment
} インターフェース型のスライスに構造体のスライスを代入することはできない
main() 関数を見てください。
最初に Human インターフェース変数 human に PoliceOfficer 型のポインタ policeOfficer を代入しています。
これは問題なく動作します。
次に Human インターフェース型のスライス humans に PoliceOfficer 型のポインタのスライス policeOfficers を代入しようとしていますが、これはエラーになってしまいます。
理由は Go Interface Slice (Japanese) に記載されています。
[]interface{}の変数はインターフェースではありません!これは要素型がたまたまinterface{}のスライスなのです。
スライスの要素のデータ長がインターフェースと構造体で異なることにより代入できないといわけです。
ではどうすれば良いかと言うと、少し面倒ですが for ループを使って1個ずつ要素を代入します。
コード例は下記です。
var humans []Human
policeOfficers := []*PoliceOfficer{policeOfficer}
for _, po := range policeOfficers {
humans = append(humans, po)
}
以上です。
この記事では、Go の interface 型のスライスに struct 型のスライスを代入できない理由と解決方法を説明しました。
コメントを送る
コメントはブログオーナーのみ閲覧できます