On Sun, 19 Mar 2017 13:51:05 -0700 (PDT) aktungmak <aktung...@gmail.com> wrote:
> I am trying to write a function that initializes a generic > collection. For adding new items to the collection, the user > specifies a constructor which takes one argument and returns a > pointer to the struct that will be inserted in the collection, and > also sets fields to initial values. For example: > > func Constructor(id int) *NewItemX ... > func Constructor(id int) *NewItemY ... > func Constructor(id int) *NewItemZ ... > > In the constructor for the collection, I want to accept any function > which has this general form, although the return type will be > different for each struct. At first, I thought this might work: > > func NewCollection(itemCtr func(int) interface{}) *Collection ... > > but of course, trying to pass Constructor fails during compilation > since the types *NewItemX and interface{} do not match: > > .\Collection_test.go:xx: cannot use NewItemX (type func(int) > *NewItemX) as type func(int) interface {} in argument to NewCollection I think that's because of [1]. > I could just do this: > > func NewCollection(itemCtr interface{}) *Collection > > but then I would have to do some runtime checks using reflect to make > sure that it is a func etc and I lose compile-time checking of types. > > How can I express this best in go? I'd say that your constructor function's type should be defined to return an interface{} but the actual function should return values of concrete types -- *NewItemX, *NewItemY etc. Something like this ([2] on playground): ------------------------------8<------------------------------ package main type ItemCtor func() interface{} type Foo struct{} type FooCollection []*Foo func ConctructFooCollection(ctor ItemCtor) FooCollection { out := make(FooCollection, 10) for i := range out { out[i] = ctor().(*Foo) } return out } func userProvidedFooPtrCtor() interface{} { return &Foo{} } func main() { _ = ConctructFooCollection(userProvidedFooPtrCtor) } ------------------------------8<------------------------------ This supposes your collection actually knows the types of its elements. If it doesn't, we need more context to know, probably. 1. https://golang.org/doc/faq#covariant_types 2. https://play.golang.org/p/l-K5knQCd5 -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.