產生原因
調用 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()
直接傳入結構體- 使用
Elem()
獲取指針指向的元素Value
immutable := reflect.ValueOf(article).Elem()