FAQ
You almost never need a pointer to an interface

func to_struct_ptr(obj interface{}) interface{} {
vp := reflect.New(reflect.TypeOf(obj))
return vp.Interface()
}

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



On Monday, December 7, 2015 at 10:39:44 AM UTC-5, smith.wi...@gmail.com
wrote:
I have a use-case where I'm trying to create some middle-ware to mediate
between martini-binding and gorp in a generic way.

The struct is passed in by-value so wrap a reflect.Value around a pointer
to it (as per the laws of reflection), but I don't seem to be able to
convert that into a struct pointer. I've tried various approaches
including using reflect.Value.Addr() and reflect.Value.Convert() on a
reflect.PtrTo() of the struct type, all of which panic.

What is the correct strategy to accomplish this? This is what I'm doing
right now -- which I think is the reflect way of doing `return
&obj.(*MyStruct)` where obj is an interface{} to a struct:


func to_struct_ptr(obj interface{}) interface{} {

fmt.Println("obj is a", reflect.TypeOf(obj).Name())
// Must take the value on the pointer to the object (see laws of
reflection)
v := reflect.ValueOf(&obj)
// Create a pointer type to the underlying element type
ptrtype := reflect.PtrTo(reflect.TypeOf(obj))
fmt.Println("ptrtype is", ptrtype)
// Convert the *interface{} to a *Cat
vp := v.Convert(ptrtype)
// NOTE: `v.Convert(ptrtype)` fails with:
//
// panic: reflect.Value.Convert: value of type *interface {} cannot
be converted to type *main.Cat
//

// Return a `Cat` pointer to obj -- i.e. &obj.(*Cat)
return vp.Interface()
}


See Go playground example: http://play.golang.org/p/BFWyXnkUuF

Thanks!
--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Smith Winston 101 at Dec 7, 2015 at 3:59 pm

    On Monday, December 7, 2015 at 10:53:38 AM UTC-5, James Bardin wrote:
    You almost never need a pointer to an interface

    func to_struct_ptr(obj interface{}) interface{} {
    vp := reflect.New(reflect.TypeOf(obj))
    return vp.Interface()
    }

    http://play.golang.org/p/UwshHBJPGi
    That's a new (now empty) Cat though!

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • James Bardin at Dec 7, 2015 at 4:16 pm

    On Mon, Dec 7, 2015 at 10:59 AM, wrote:
    On Monday, December 7, 2015 at 10:53:38 AM UTC-5, James Bardin wrote:

    You almost never need a pointer to an interface

    func to_struct_ptr(obj interface{}) interface{} {
    vp := reflect.New(reflect.TypeOf(obj))
    return vp.Interface()
    }

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

    That's a new (now empty) Cat though!
    Sorry I misunderstood. You can set the element's value once you have a
    pointer to the correct type:

    func to_struct_ptr(obj interface{}) interface{} {
         val := reflect.ValueOf(obj)
         vp := reflect.New(val.Type())
         vp.Elem().Set(val)
         return vp.Interface()
    }

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Smith Winston 101 at Dec 7, 2015 at 6:14 pm

    On Monday, December 7, 2015 at 11:16:22 AM UTC-5, James Bardin wrote:
    Sorry I misunderstood. You can set the element's value once you have a
    pointer to the correct type:

    func to_struct_ptr(obj interface{}) interface{} {
    val := reflect.ValueOf(obj)
    vp := reflect.New(val.Type())
    vp.Elem().Set(val)
    return vp.Interface()
    }
    I got that working in my example -- here's the final solution:
      http://play.golang.org/p/hYnsAijyCE

    *NOTE*: I found that these two are *not* equivalent

    vp.Elem().Set(reflect.ValueOf(obj)) // this works!
    vp.Elem().Set(reflect.ValueOf(&obj).Elem()) // panics with "panic:
    reflect.Set: value of type interface {} is not assignable to type main.Cat"

    Many thanks!

    -W.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Roberto Zanotto at Dec 7, 2015 at 5:38 pm
    If you store a non-pointer inside an interface{} or a reflect.Value, that
    value will be not settable and you can not get a pointer back safely. The
    line:
    // Must take the value on the pointer to the object (see laws of reflection)
    v := reflect.ValueOf(&obj)
    is wrong: &obj is a pointer to an interface{} doesn't have (almost)
    anything to do with your Cat.
    You can get a pointer back only if you use something like reflect.New(Cat)
    or reflect.ValueOf(new(Cat)).
    Also note that with (interface{})(Cat{}) (so, not a pointer to Cat, the
    struct directly), a copy of the Cat is made. Even if you got the pointer
    out of the interface with unsafe, it would be a pointer to a copy of your
    Cat.

    On Monday, December 7, 2015 at 4:39:44 PM UTC+1, smith.wi...@gmail.com
    wrote:
    I have a use-case where I'm trying to create some middle-ware to mediate
    between martini-binding and gorp in a generic way.

    The struct is passed in by-value so wrap a reflect.Value around a pointer
    to it (as per the laws of reflection), but I don't seem to be able to
    convert that into a struct pointer. I've tried various approaches
    including using reflect.Value.Addr() and reflect.Value.Convert() on a
    reflect.PtrTo() of the struct type, all of which panic.

    What is the correct strategy to accomplish this? This is what I'm doing
    right now -- which I think is the reflect way of doing `return
    &obj.(*MyStruct)` where obj is an interface{} to a struct:


    func to_struct_ptr(obj interface{}) interface{} {

    fmt.Println("obj is a", reflect.TypeOf(obj).Name())
    // Must take the value on the pointer to the object (see laws of
    reflection)
    v := reflect.ValueOf(&obj)
    // Create a pointer type to the underlying element type
    ptrtype := reflect.PtrTo(reflect.TypeOf(obj))
    fmt.Println("ptrtype is", ptrtype)
    // Convert the *interface{} to a *Cat
    vp := v.Convert(ptrtype)
    // NOTE: `v.Convert(ptrtype)` fails with:
    //
    // panic: reflect.Value.Convert: value of type *interface {} cannot
    be converted to type *main.Cat
    //

    // Return a `Cat` pointer to obj -- i.e. &obj.(*Cat)
    return vp.Interface()
    }


    See Go playground example: http://play.golang.org/p/BFWyXnkUuF

    Thanks!
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedDec 7, '15 at 3:53p
activeDec 7, '15 at 6:14p
posts5
users3
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase