簡體   English   中英

通過Go中的反射為結構成員分配值

[英]Assigning a value to struct member through reflection in Go

我有一個帶有成員A,B,C字符串的struct v。 使用反射,我可以獲取字段名稱及其值:

typ := v.Type()
for i := 0; i < v.NumField(); i++ {
    // gets us a StructField
    fi := typ.Field(i)
    fieldname := fi.Name
    fmt.Println(fieldname)
    val := fmt.Sprintf("%v", v.Field(i).Interface())
 }

因為我有名稱,並且可以獲取值OUT,所以可以為字段分配新值嗎? 我基本上想做的是:

v.Field(fieldname).Interface() = "new value"

但這顯然行不通。 如果僅知道字段名稱,是否可以將值分配給結構?

在實踐中,我嘗試將map[string]string值分配給結構中的相應字段,其中結構和映射定義可能會隨着時間的變化而擴展,並且映射中包含的值可能會大於或小於結構。 我已經考慮過使用JSON進行此操作,但是這種方法讓我有些不寒而栗,因為使用反射來“幾乎”到達那里是多么容易!

謝謝,肯

對的,這是可能的。

介紹

由於要訪問和修改變量(或字段)的值,因此需要使用reflect.Value類型而不是reflect.Type 您可以使用reflect.ValueOf()獲取它。 同樣,為了通過反射來修改它,您還需要傳遞要修改的struct或值的地址(指針)(否則,您只能讀取它,而不能修改它)。

但你不希望修改地址/指針,但針對性的價值,所以你必須從以“導航” Value的指針的Value的變量尖(結構),這是什么Value.Elem()是對於。 看起來像這樣: reflect.ValueOf(&s).Elem()

您可以使用Value.FieldByName()方法獲得結構字段的Value ,由於我們將指針的地址傳遞給ValueOf()函數,因此該方法可設置

編碼

一旦理解,該代碼比簡介簡單得多。 您也可以在Go Playground上嘗試一下:

var s struct {
    A, B, C string
}
s.A, s.B, s.C = "a1", "b2", "c3"

fmt.Println("Before:  ", s)

v := reflect.ValueOf(&s).Elem()

v.FieldByName("A").SetString("2a")
v.FieldByName("B").SetString("2b")
v.FieldByName("C").SetString("2c")

fmt.Println("After:   ", s)

// Using a map:
m := map[string]string{"A": "ma", "B": "mb", "C": "mc"}
for mk, mv := range m {
    v.FieldByName(mk).SetString(mv)
}

fmt.Println("From Map:", s)

輸出:

Before:   {a1 b2 c3}
After:    {2a 2b 2c}
From Map: {ma mb mc}

我建議閱讀此博客文章,以了解Go中反射的基礎知識:

反射定律

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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