2 回答

TA貢獻(xiàn)1772條經(jīng)驗(yàn) 獲得超8個(gè)贊
正如錯(cuò)誤call of reflect.flag.mustBeAssignable on zero Value所說(shuō),newTValue.Elem().FieldByName(newTTag).CanSet()在您的代碼中并根據(jù)文檔返回 false
Set 將 x 分配給值 v。如果 CanSet 返回 false,它會(huì)發(fā)生混亂。與 Go 一樣,x 的值必須可分配給 v 的類型。
這是更正的代碼,它從一個(gè)對(duì)象中獲取字段并將值分配給另一個(gè)對(duì)象。
package main
import (
"fmt"
"reflect"
)
type T struct {
A int `json:"aaa" test:"AA"`
B string `json:"bbb" test:"BB"`
}
type newT struct {
AA int
BB string
Testaaa string
}
func main() {
t := T{
A: 123,
B: "hello",
}
tt := reflect.TypeOf(t)
tv := reflect.ValueOf(t)
newT := &newT{}
newTValue := reflect.ValueOf(newT)
for i := 0; i < tt.NumField(); i++ {
field := tt.Field(i)
newTTag := field.Tag.Get("test")
tValue := tv.Field(i)
newTfield := newTValue.Elem().FieldByName(newTTag)
if newTfield.CanSet() {
newTfield.Set(tValue)
}
}
fmt.Println(newT)
}

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超6個(gè)贊
第一的:
for i := 0; i < tt.NumField(); i++ {
field := tt.Field(i)
這里的每一步都會(huì)遍歷 type 實(shí)例的字段T。因此,這些字段將是A——或者更確切地說(shuō),是字段描述符,它的NameisA和它描述了一個(gè)帶有 json 和 test 標(biāo)記的 int ——然后B(如果我們?cè)龠M(jìn)一步,具有相同的挑剔細(xì)節(jié))。
由于兩個(gè)字段描述符只有兩個(gè)Get-able 項(xiàng)目,因此您可能打算使用Get("test"),如Guarav Dhiman 的回答。
但是,如果你這樣做,結(jié)果是"testaaa"你在場(chǎng)上A和"testbbb"場(chǎng)上的時(shí)候B。如果我們對(duì) Guarav 的代碼多加注解:
for i := 0; i < tt.NumField(); i++ {
field := tt.Field(i)
newTTag := field.Tag.Get("test")
fmt.Printf("newTTag = %#v\n", newTTag)
tValue := tv.Field(i)
newTfield := newTValue.Elem().FieldByName(newTTag)
fmt.Printf("newTfield = %#v\n", newTfield)
if newTfield.CanSet() {
newTfield.Set(tValue)
}
}
我們將看到這個(gè)輸出:
newTTag = "testaaa"
newTfield = <invalid reflect.Value>
newTTag = "testbbb"
newTfield = <invalid reflect.Value>
我們需要的是使test每個(gè)標(biāo)簽名稱中的字符串成為類型中的字段newT:
type T struct {
A int `json:"aaa" test:"AA"`
B string `json:"bbb" test:"BB"`
}
(Guarav 實(shí)際上已經(jīng)這樣做了,但沒有提及。)現(xiàn)在程序產(chǎn)生了(大概)你想要的:
&{123 hello}
- 2 回答
- 0 關(guān)注
- 252 瀏覽
添加回答
舉報(bào)