例えば以下のような依存関係で Interface の Slice を期待しているメソッドがあったとして
これを超簡易に書いたらこうなる
main.go
package main
import (
"fmt"
"github.com/somen440/zatsu/golang/interface_slice/converter"
"github.com/somen440/zatsu/golang/interface_slice/structure"
)
var (
c *converter.Converter
_ migration.StructureInterface = &structure.Structure{}
)
func init() {
c = converter.NewConverter()
}
func main() {
sl := []*structure.Structure{
structure.NewStructure("up1"),
structure.NewStructure("up2"),
structure.NewStructure("up3"),
}
m := c.ToMigrate(sl)
fmt.Println(m)
}
migration/migration.go
package migration
import "bytes"
type StructureInterface interface {
GetUp() string
}
type Migration struct {
UpList []string
}
func NewMigration(list []StructureInterface) *Migration {
rs := &Migration{}
for _, v := range list {
rs.UpList = append(rs.UpList, v.GetUp())
}
return rs
}
func (m *Migration) String() string {
var out bytes.Buffer
out.WriteString("*************************** Up ***************************" + "\\n")
for _, up := range m.UpList {
out.WriteString(up + "\\n")
}
return out.String()
}
converter/converter.go
package converter
import (
"github.com/somen440/zatsu/golang/interface_slice/migration"
"github.com/somen440/zatsu/golang/interface_slice/structure"
)
type Converter struct{}
func NewConverter() *Converter {
return &Converter{}
}
func (c *Converter) ToMigrate(list []*structure.Structure) *migration.Migration {
rs := []migration.StructureInterface{}
for _, v := range list {
rs = append(rs, v)
}
// cannot use list (variable of type []*structure.Structure) as []migration.StructureInterface value in argument to append
// rs = append(rs, list...)
return migration.NewMigration(rs)
}
structure/structure.go
package structure
type Structure struct {
Up string
}
func NewStructure(up string) *Structure {
return &Structure{
Up: up,
}
}
func (s *Structure) GetUp() string {
return s.Up
}
output
❯ go run .
*************************** Up ***************************
up1
up2
up3
*Structure
は StructureInterface
を実装しており, 単体であれば StructureInterface
の宣言をパスできる( main.go L13 )が, []*Structure
は []StructureInterface
をパスできない。感覚的には, Interface を実装した struct の配列だからいいんじゃね?と思うんだけども, slice の仕様上, struct と interface{} の slice は明確に分かれている。