我有一段反射代碼,它嘗試按名稱獲取結構上的欄位,然后檢查該欄位是否存在:
type test struct {
A bool
B bool
}
t := new(test)
metaValue := reflect.ValueOf(t).Elem()
field := metaValue.FieldByName(name)
if field.IsZero() {
glog.Errorf("Field %s was not on the struct", inner)
}
根據 上的檔案FieldByName,如果未找到欄位,此函式應回傳零值。但是,下一行因錯誤而恐慌:
panic: reflect: call of reflect.Value.IsZero on zero Value
goroutine 268 [running]:
reflect.Value.IsZero({0x0, 0x0, 0x112a974})
reflect/value.go:1475 0x27f
根據此 GitHub 問題,僅當 Value 包含 nil(即無型別)時才會發生這種情況,并且IsValid應改為使用。為什么會這樣?
uj5u.com熱心網友回復:
Value.IsZero()報告包裝的值是否是其型別的零值。這與reflect.Value本身為零(其零值reflect.Value是結構)不同。
另請注意,t在您的代碼中不是結構值,而是指向結構的指標。使用Value.Elem()以了解它們的包裝結構值(或者不從一開始的指標)。
如果該欄位不存在,則Value.FieldByName()回傳 的零值reflect.Value,而不是包含reflect.Value某種型別零值的非零值;如果未找到欄位,則沒有型別資訊。
因此,要檢查該欄位是否不存在,請reflect.Value通過將其與reflect.Value{}以下進行比較來檢查其本身是否為零:
if field == (reflect.Value{}) {
log.Printf("Field %s was not on the struct", name)
}
測驗它:
type test struct {
A bool
B bool
x bool
}
v := new(test)
metaValue := reflect.ValueOf(v).Elem()
for _, name := range []string{"A", "x", "y"} {
field := metaValue.FieldByName(name)
if field == (reflect.Value{}) {
log.Printf("Field %s was not on the struct", name)
}
}
這將輸出(在Go Playground上嘗試):
2009/11/10 23:00:00 Field y was not on the struct
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/343564.html
下一篇:DoctrineQueryBuilder/DQL-如何使用WHEREcolumn=BINARY'text'撰寫查詢
