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