产生原因
调用 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()