2

I've seen a few examples of reflection around this topic, but I can't find anything that solves this issue. It feels a little convoluted, but the alternative is a massive amount of repetition so I thought I'd give it a try.

I have a function that returns a function (handler). The wrapping function passes in an instance of a struct. I need the inner function to create a slice of pointers to that struct type:

func createCollectionHandler(app *appSession, record interface{}, name string) func(res http.ResponseWriter, req *http.Request) {
    return func(res http.ResponseWriter, req *http.Request) {
        res.Header().Set("Content-Type", "application/json")

        // This line needs to be dynamic:
        var result []*Person

        err := meddler.QueryAll(app.MysqlDB, &result, "select * from "+name)
        if err != nil {
            log.Fatal(err)
        }
        json, err := json.MarshalIndent(result, "", " ")
        if err != nil {
            log.Println(err)
        }
        res.Write([]byte(json))
        return
    }
}
1
  • 1
    That should work fine, maybe meddler is doing something wrong? Commented Oct 27, 2015 at 16:35

1 Answer 1

5

You can create a slice using reflect and an example of the type like so:

var t *MyType

typeOfT := reflect.TypeOf(t)
sliceOfT := reflect.SliceOf(typeOfT)

s := reflect.MakeSlice(sliceOfT, 0, 0).Interface()

In order to pass a pointer to the slice without knowing the type, you can create the pointer first, then set the slice value:

ptr := reflect.New(sliceOfT)
ptr.Elem().Set(reflect.MakeSlice(sliceOfT, 0, 0))
s := ptr.Interface()

http://play.golang.org/p/zGSqe45E60

Sign up to request clarification or add additional context in comments.

5 Comments

@thwd: I know ;) just showing the type assertion in case the OP wasn't sure how to get the concrete type out of the reflect.MakeSlice.
Hey there. I tried that already, but thought that perhaps I was missing something because I get the following error: ScanAll called with pointer to non-slice: *interface {} which is being emitted from meddler. I'm not married to using meddler, just want a quick and simple way of querying MySQL. I'd happily remove it.
@i0n: you have to assert the type before you take the address, since you can't use a pointer to an interface. I'll add an example about creating a pointer with reflect if that's what you're looking for.
Hey, thanks for the help! I think what I need to do is create a slice of pointers to a struct type that is passed in through the functions interface. The resulting slice needs to have type slice etc when it is introspected, because I think this is what is causing meddler to blow up. Is this possible?
@i0n: The first example makes a []*MyType, the second makes a *[]*MyType. Those are the actual types which will come out of the interface{}. I think the second example is what you're looking for, since you want the pass the pointer to meddler.QueryAll immediately.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.