天天看點

【Go】panic: reflect: call of reflect.Value.FieldByName on ptr Value

産生原因

調用

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()})
	}
}
           

解決辦法

  1. ValueOf()

    直接傳入結構體
  2. 使用

    Elem()

    擷取指針指向的元素Value

繼續閱讀