2017-03-28 32 views
1

我正在嘗試使用反射從struct值中獲取字段。獲取子結構字段中的轉到

package main 

import (
    "fmt" 
    "reflect" 
) 

type Vertex struct { 
    X   string 
    Y   string 
    SubVertex SubVertex 
} 
type SubVertex struct { 
    Z string 
} 

func get_field(v Vertex, field string) string { 
    r := reflect.ValueOf(v) 
    f := reflect.Indirect(r).FieldByName(field) 
    return f.String() 
} 

func main() { 
    v := Vertex{"a", "b", SubVertex{"c"}} 

    fmt.Println(get_field(v, "X")) 
    fmt.Println(get_field(v, "Y")) 
    fmt.Println(get_field(v, "Z")) // Invalid Value 
} 

我得到無效值在第三種情況下,當我試圖讓Z字段的值。如果SubVertex是一個匿名字段,這將工作,但我需要使用一個命名字段。

我該如何做這項工作?

+2

工作正常操場https://play.golang.org/p/fgnOdNRDA0 – RayfenWindspear

+0

不適合我...... HTTPS: //play.golang.org/p/bMCKdzFe0i AB <無效值> – irom

+1

我編輯了這個問題 - 最初是因爲工作代碼和散文中描述的一些稍微難以理解的變化一起呈現的混淆,問題。 –

回答

4

在這種情況下,您必須以與正常訪問值相同的方式使用反射包。所以

v.X // a 
v.Y // b 
v.SubVertex.Z // c 

成爲

r := reflect.ValueOf(v) 
x := reflect.Indirect(r).FieldByName("X") 
x.String() // a 
... 
z := reflect.Indirect(r).FieldByName("SubVertex").FieldByName("Z") 
z.String() // c 

注意FieldByName()上調用Value並返回一個Value,所以它的工作原理大致相同,只需定期訪問它。還請注意,根據文檔:

間接返回v指向的值。如果v是一個零指針,則間接返回一個零值。如果v不是指針,間接回報訴

所以調用Indirect()將是一個空操作,但如果你決定給它在未來的指針會保護它從具有崩潰。

至於你的功能,這將工作

func get_field(v Vertex, field string) string { 
    r := reflect.ValueOf(v) 
    if field == "Z" { 
     f := reflect.Indirect(r).FieldByName("SubVertex").FieldByName(field) 
     return f.String() 
    } 
    f := reflect.Indirect(r).FieldByName(field) 

    return f.String() 
} 

https://play.golang.org/p/eZyTl8OSTZ