簡體   English   中英

恐慌:反映:在接口值上調用 reflect.Value.FieldByName

[英]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)

在 Go 操場上運行它

接口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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM