Query about reflect.Value.FieldByName

1,578 views
Skip to first unread message

Mark Summerfield

unread,
May 12, 2011, 6:40:38 AM5/12/11
to golang-nuts
Hi,

I don't seem to understand how reflect.Value.FieldByName() works:

package main
import (
"fmt"
"reflect"
)
func main() {
type X struct {
a int "one"
b int "two"
}
x := X{5, 7}
v := reflect.ValueOf(interface{}(x))
fmt.Println(x, v, v.Kind(), v.IsValid(), v.FieldByName("two"))
}

Produces:

{5 7} <main.X Value> struct true <invalid Value>

According to the docs this means that v.FieldByName("two") has returned
the zero value; but I was expecting a reflect.Value that held int 7.

What am I doing wrong?

Thanks!

$ hg identify
95d2ce135523+ (release-branch.r57) release/release.r57.1

--
Mark Summerfield, Qtrac Ltd, www.qtrac.eu
C++, Python, Qt, PyQt - training and consultancy
"Advanced Qt Programming" - ISBN 0321635906
http://www.qtrac.eu/aqpbook.html

Jan Mercl

unread,
May 12, 2011, 6:48:15 AM5/12/11
to golan...@googlegroups.com
On Thursday, May 12, 2011 12:40:38 PM UTC+2, Mark wrote:
Hi,

I don't seem to understand how reflect.Value.FieldByName() works:

package main
import (
    "fmt"
    "reflect"
    )
func main() {
    type X struct {
        a int "one"
        b int "two"
    }
    x := X{5, 7}
    v := reflect.ValueOf(interface{}(x))
    fmt.Println(x, v, v.Kind(), v.IsValid(), v.FieldByName("two"))
}

Produces:

{5 7} <main.X Value> struct true <invalid Value>

According to the docs this means that v.FieldByName("two") has returned
the zero value; but I was expecting a reflect.Value that held int 7.

What am I doing wrong?

    v.FieldByName("two")

Type X has no field named "two". Try e.g. "a".

Mark Summerfield

unread,
May 12, 2011, 7:08:16 AM5/12/11
to golan...@googlegroups.com, jan....@nic.cz
Hi Jan,

That works perfectly!

But I'm still curious as to how I can access struct field annotations?

Thanks:-)

--
Mark Summerfield, Qtrac Ltd, www.qtrac.eu
C++, Python, Qt, PyQt - training and consultancy

"Programming in Go" - ISBN 0321774639
http://www.qtrac.eu/gobook.html

Dmitry Chestnykh

unread,
May 12, 2011, 7:09:43 AM5/12/11
to golan...@googlegroups.com, jan....@nic.cz
They are called tags: http://golang.org/pkg/reflect/#StructField

-Dmitry

Mark Summerfield

unread,
May 12, 2011, 8:45:46 AM5/12/11
to golan...@googlegroups.com, jan....@nic.cz
On Thu, 12 May 2011 03:48:15 -0700 (PDT)
Jan Mercl <jan....@nic.cz> wrote:
> On Thursday, May 12, 2011 12:40:38 PM UTC+2, Mark wrote:
> >
> > Hi,
> >
> > I don't seem to understand how reflect.Value.FieldByName() works:
> >
> > package main
> > import (
> > "fmt"
> > "reflect"
> > )
> > func main() {
> > type X struct {
> > a int "one"
> > b int "two"
> > }
> > x := X{5, 7}
> > v := reflect.ValueOf(interface{}(x))
> > fmt.Println(x, v, v.Kind(), v.IsValid(), v.FieldByName("two"))
> > }
> >
> > Produces:
> >
> > {5 7} <main.X Value> struct true <invalid Value>
> >
> > According to the docs this means that v.FieldByName("two") has
> > returned the zero value; but I was expecting a reflect.Value that
> > held int 7.

v.FieldByName("b") should return (reflect.StructField, bool), according
to the docs, but actually returns a reflect.Value (which has the
expected int).

So I think that maybe the docs are wrong?

--
Mark Summerfield, Qtrac Ltd, www.qtrac.eu
C++, Python, Qt, PyQt - training and consultancy

"Rapid GUI Programming with Python and Qt" - ISBN 0132354187
http://www.qtrac.eu/pyqtbook.html

Jan Mercl

unread,
May 12, 2011, 8:51:00 AM5/12/11
to golan...@googlegroups.com, jan....@nic.cz
On Thursday, May 12, 2011 2:45:46 PM UTC+2, Mark wrote:

v.FieldByName("b") should return (reflect.StructField, bool), according
to the docs, but actually returns a reflect.Value (which has the
expected int).

No. The 'v' variable was created using reflect.ValueOf(), so it reflects values. To reflect types use reflect.TypeOf()

So I think that maybe the docs are wrong?

I think the docs are correct.

Mark Summerfield

unread,
May 12, 2011, 11:51:45 AM5/12/11
to golan...@googlegroups.com, jan....@nic.cz

Yes, sorry, my mistake (I mixed up TypeOf() and ValueOf()):

package main
import (
"fmt"
"reflect"
)
func main() {
type X struct {
a int "one"
b int "two"
}
x := X{5, 7}

v := reflect.ValueOf(x)
s := reflect.TypeOf(x)
f, ok := s.FieldByName("a")
fmt.Println(x, v, v.Kind(), v.IsValid(), v.FieldByName("b"))
fmt.Println(s, f, f.Tag, ok)
}

Correctly outputs:
{5 7} <main.X Value> struct true <int Value>
main.X {main a int one 0 [0] false} one true


--
Mark Summerfield, Qtrac Ltd, www.qtrac.eu
C++, Python, Qt, PyQt - training and consultancy

Reply all
Reply to author
Forward
0 new messages