我有這樣的演示數據結構。正如你所看到的,foo
有一個嵌入式指針bar
:反映認爲struct Value也是ptr?
type foo struct {
*bar
}
type bar struct {
S []byte
}
而且我使用的reflect
包這樣的:
func test(x interface{}) {
var v = reflect.ValueOf(x)
if v.Kind() == reflect.Struct {
fmt.Println("was a struct")
// panic: reflect: call of reflect.Value.Elem on struct Value
// v = v.Elem()
// panic: reflect: call of reflect.Value.Field on ptr Value
v = v.FieldByName("S")
}
}
func main() {
var f foo
test(f)
fmt.Println(string(f.S))
}
所以v.Kind()
是公認的reflect.Struct
,但如果我嘗試通過使用.FieldByName("S")
來將它當作一個結構對待,它會因爲它認爲v
是ptr
而發生混亂。
所以後來如果我嘗試致電.Elem()
把它當作一個ptr
,其恐慌,因爲它認爲v
是一個struct
。
我試過reflect.Indirect()
,以及其他一些事情,但我不知道如何獲得嵌入式指針的字段。
有沒有辦法將reflect.Value
表示從嵌入式指針轉換爲結構?
演示:http://play.golang.org/p/n0eea6XW3I
編輯:也試過v = v.FieldByName("bar")
,但得到:
panic: runtime error: invalid memory address or nil pointer dereference
我必須查看文件以確保,但我的直覺是,可能是嵌入式類型混淆它。 – LinearZoetrope
這絕對是令人困惑的嵌入式類型。嘗試更改欄不是一個指針,它不會崩潰。修改:刪除對f.S的引用,併爲*欄指定一個名稱並且它可以工作。我正在瀏覽文檔以查看是否在任何地方提及此行爲。 – LinearZoetrope
@Jsor:謝謝,是的,我可以看到那裏會有些混亂。 「反射」中找不到任何特別處理嵌入式指針的內容。 –