産生原因
調用
FieldByName()
方法時,調用者與預期類型不相符。
// 錯誤代碼
func setNewArticleInfoToCache(article *Article) {
fields := []string{
"Title", "Abstract", "ID", "AuthorID", "CreateTime",
}
immutable := reflect.ValueOf(article)
// immutable := reflect.ValueOf(article).Elem()
for _, field := range fields {
val := immutable.FieldByName(field)
fmt.Println(val)
}
}
//panic: reflect: call of reflect.Value.FieldByName on ptr Value [recovered]
// panic: reflect: call of reflect.Value.FieldByName on ptr Value
由于傳遞給
reflect.ValueOf
的
article
是一個指針,是以得到的
immutable
的類型是
Ptr
, 而
FieldByName
方法需要調用者類型為
Struct
:
func (v Value) FieldByName(name string) Value {
// 必須是 Struct 類型
v.mustBe(Struct)
if f, ok := v.typ.FieldByName(name); ok {
return v.FieldByIndex(f.Index)
}
return Value{}
}
func (f flag) mustBe(expected Kind) {
if Kind(f&flagKindMask) != expected {
// 此處抛出的異常
panic(&ValueError{methodName(), f.kind()})
}
}
解決辦法
-
直接傳入結構體ValueOf()
- 使用
擷取指針指向的元素ValueElem()