golang - 指针的特质

时间:2014-06-20 22:26:03

标签: go

需要帮助理解为什么会中断。可以使用指针或值调用PrintFoo。为什么不使用NumField?

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

type A struct {
   foo string
}

func (a *A) PrintFoo(){
    fmt.Println("Foo value is " + a.foo)
}

func main() {
        a := &A{foo: "afoo"}

        (*a).PrintFoo() //Works - no problem
        a.PrintFoo() //Works - no problem
        reflect.TypeOf(*a).NumField() //Works - no problem - Type = main.A
        reflect.TypeOf(a).NumField() //BREAKS! - Type = *main.A
}

1 个答案:

答案 0 :(得分:5)

来自documentation

// NumField returns the number of fields in the struct v.
// It panics if v's Kind is not Struct.
func (v Value) NumField() int

你是在一个指针上调用它,你必须在一个结构上调用它,而不是example

fmt.Println(reflect.Indirect(reflect.ValueOf(a)).NumField())
fmt.Println(reflect.Indirect(reflect.ValueOf(*a)).NumField())

如果您不确定自己的值是否为指针,请使用reflect.Indirect

  

间接返回v指向的值。如果v是nil指针,   间接返回零值。如果v不是指针,则间接返回   诉

//编辑:

NumField会在Value上被调用,而不是您的实际对象,例如:

func main() {
    a := &A{foo: "afoo"}
    fmt.Printf("%#v\n", reflect.TypeOf(*a))
    fmt.Printf("%#v\n", reflect.TypeOf(a))
}

你会得到:

//*a
&reflect.rtype{size:0x8, ...... ptrToThis:(*reflect.rtype)(0xec320)} 
//a
&reflect.rtype{size:0x4, ...... ptrToThis:(*reflect.rtype)(nil)}

正如你所知,它是一个完全不同的野兽。

  • 第一个包含有关指针的信息,因此ptrToThis指向实际的结构。
  • 第二个包含有关结构本身的信息。