例えば以下のような依存関係で Interface の Slice を期待しているメソッドがあったとして

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/c040fd88-609f-40df-9d82-2358ee3344b9/RP2z3e9048JxVOef_GclO4YiBBInD1QNSoKNuJ1tYnRAkuiOzY3IVlbcCfayYWdIL2NTZRsPWX4bD5QQm7WHO4iJ8uu3evPKh5mHZBZQzwBpmk5gB2TvDo3Ielqa0wnnuESFyg9qKN0w_-UNM6cGW7QymjR-mQ4JHtEtYVMkDYBBtflPWMbODYzevrVGZwPO7w6S_QKxzGC0.png

これを超簡易に書いたらこうなる

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

*StructureStructureInterface を実装しており, 単体であれば StructureInterface の宣言をパスできる( main.go L13 )が, []*Structure[]StructureInterface をパスできない。感覚的には, Interface を実装した struct の配列だからいいんじゃね?と思うんだけども, slice の仕様上, struct と interface{} の slice は明確に分かれている。