変数やメソッドの仮引数としてインターフェース型のスライスを定義しておき、実際には構造体のスライスを渡したいというケースがあります。
これはスライスでなければ上手く動きます。しかし、スライスではエラーになってしまいます。
次のようなコードです。
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 型のスライスを代入できない理由と解決方法を説明しました。
 
  
 
コメントを送る
コメントはブログオーナーのみ閲覧できます