On Sun, 19 Mar 2017 13:51:05 -0700 (PDT)
aktungmak <[email protected]> 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 [email protected].
For more options, visit https://groups.google.com/d/optout.