[英]panic: reflect: call of reflect.Value.FieldByName on interface Value
我有一個interface{}
類型的變量,我想使用反射更改字段的值。 我該怎么做? 由於其他要求,變量必須是interface{}
類型。 如果變量不是interface{}
類型,則一切正常,否則代碼拋出
reflect: call of reflect.Value.FieldByName on interface Value
我的代碼
package main
import (
"fmt"
"reflect"
)
func main() {
a := struct {
Name string
}{}
// works
reflect.ValueOf(&a).Elem().FieldByName("Name").SetString("Hello")
fmt.Printf("%#v\n", a)
var b interface{}
b = struct {
Name string
}{}
// panics
reflect.ValueOf(&b).Elem().FieldByName("Name").SetString("Hello")
fmt.Printf("%#v\n", b)
}
應用程序必須調用Elem()
兩次才能獲取結構值:
reflect.ValueOf(&b).Elem().Elem().FieldByName("Name").SetString("Hello")
第一次調用Elem()
取消引用interface{}
的指針。 第二次調用Elem()
獲取接口中包含的值。
通過此更改,恐慌是reflect.Value.SetString using unaddressable value
。
應用程序不能直接在接口中包含的結構值上設置字段,因為接口中包含的值是不可尋址的。
將struct值復制到臨時變量中,設置臨時變量中的字段,將臨時變量復制回接口。
var b interface{}
b = struct {
Name string
}{}
// v is the interface{}
v := reflect.ValueOf(&b).Elem()
// Allocate a temporary variable with type of the struct.
// v.Elem() is the vale contained in the interface.
tmp := reflect.New(v.Elem().Type()).Elem()
// Copy the struct value contained in interface to
// the temporary variable.
tmp.Set(v.Elem())
// Set the field.
tmp.FieldByName("Name").SetString("Hello")
// Set the interface to the modified struct value.
v.Set(tmp)
fmt.Printf("%#v\n", b)
接口b
使用匿名結構的值進行初始化,因此b
包含該結構的副本,並且這些值是不可尋址的。 使用指針初始化b
:
var b interface{}
b = &struct {
Name string
}{}
reflect.ValueOf(b).Elem().FieldByName("Name").SetString("Hello")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.