Creating a slice from reflect.Type

374 views
Skip to first unread message

mkri...@gmail.com

unread,
Dec 1, 2013, 10:21:08 AM12/1/13
to golan...@googlegroups.com
Hi,

Been searching FAQ, documentation, the list archives and other websites for several days, and couldn't come up with a solution.

I'm trying to create a slice from a reflect.Type which I can pass to mgo for results retrieval. See the following function:


func GetList(w http.ResponseWriter, r *http.Request, m models.RegisteredModel) {
    results := reflect.Zero(reflect.SliceOf(m.ModelStruct)).Interface()

    fmt.Printf("%T %T", results, &results)
    m.Collection.Find(bson.M{}).All(&results)
    w.Header().Set("Content-Type", "application/json")
    fmt.Fprintf(w, "%s", Response{"items": results})
}


m.ModelStruct
holds the reflect.Type of the needed struct. e.g, it's holds reflect.TypeOf of the following struct:

type Content struct {
    Itype    int          `json:"itype", bson:"it"`
    Title    string       `json:"title, "bson:"t"`
    Metadata ItemMetadata `json:"metadata", bson:"md"`
    Created  time.Time    `json:"created", bson:"c"`
    Updated  time.Time    `json:"updated", bson:"u"`
}

The function above is wrapped with a closure which maps the for each registered model type. However, trying to access that handler yields the error:

[]models.Content *interface {}2013/12/01 11:24:44 http: panic serving [::1]:39634: result argument must be a slice address

Can one create a slice from a type determined at runtime (and use it with mgo, which excepts a slice) ?

Thanks

Ian Lance Taylor

unread,
Dec 1, 2013, 11:24:35 AM12/1/13
to mkri...@gmail.com, golang-nuts
On Sun, Dec 1, 2013 at 7:21 AM, <mkri...@gmail.com> wrote:
>
> Can one create a slice from a type determined at runtime (and use it with
> mgo, which excepts a slice) ?

I don't know much about mgo, but you can create a slice from a type
determined at runtime by reflect.SliceOf and reflect.MakeSlice.

Ian

Gustavo Niemeyer

unread,
Dec 1, 2013, 12:48:41 PM12/1/13
to mkri...@gmail.com, golan...@googlegroups.com
On Sun, Dec 1, 2013 at 1:21 PM, <mkri...@gmail.com> wrote:
> results := reflect.Zero(reflect.SliceOf(m.ModelStruct)).Interface()
> fmt.Printf("%T %T", results, &results)
> m.Collection.Find(bson.M{}).All(&results)

The issue is in the logic above, and the error indicates it:

> []models.Content *interface {}2013/12/01 11:24:44 http: panic serving
> [::1]:39634: result argument must be a slice address

&results is not a slice address. It's the address of an interface
value that holds a slice value.

You can obtain an address using reflect.New instead of Zero:

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

and then don't take the address of the interface; just use it
(results, not &results).


gustavo @ http://niemeyer.net

Meir Kriheli

unread,
Dec 1, 2013, 7:19:24 PM12/1/13
to Gustavo Niemeyer, golan...@googlegroups.com
Indeed, reflect.New  resolved the issue,

Thank you
--
Reply all
Reply to author
Forward
0 new messages