我想做什么
我試圖通過一個instance的struct-包括json tags到一個func,創建一個新的instance,并設定value在field
這之后我嘗試序列(JSON),但值是空的
注意:我在 SO 上查找了大量關于通過反射設定值的文章,但似乎我錯過了一些細節
結構定義
這部分定義了帶有 json 和 xml 標簽的結構體
type Person struct {
Name string `json:"Name" xml:"Person>FullName"`
Age int `json:"Age" xml:"Person>Age"`
}
創建實體( 包裝到空介面中)
之后我創建了一個實體并將其存盤在一個interface{}- 為什么?因為在我的生產代碼中,這些東西將在func接受 a 的 a 中完成interface{}
var iFace interface{} = Person{
Name: "Test",
Age: 666,
}
創建結構體的新實體并通過反射設定值
iFaceType := reflect.TypeOf(iFace)
item := reflect.New(iFaceType)
s := item.Elem()
if s.Kind() == reflect.Struct {
fName := s.FieldByName("Name")
if fName.IsValid() {
// A Value can be changed only if it is
// addressable and was not obtained by
// the use of unexported struct fields.
if fName.CanSet() {
// change value of N
switch fName.Kind() {
case reflect.String:
fName.SetString("reflectedNameValue")
fmt.Println("Name was set to reflectedNameValue")
}
}
}
fAge := s.FieldByName("Age")
if fAge.IsValid() {
// A Value can be changed only if it is
// addressable and was not obtained by
// the use of unexported struct fields.
if fAge.CanSet() {
// change value of N
switch fAge.Kind() {
case reflect.Int:
x := int64(42)
if !fAge.OverflowInt(x) {
fAge.SetInt(x)
fmt.Println("Age was set to", x)
}
}
}
}
}
題
我究竟做錯了什么?
在生產代碼中,我用資料填充多個副本并將其添加到slice...
但這只有在json tags 保持原位并且內容以相同方式序列化時才有意義。
播放代碼示例
package main
import (
"encoding/json"
"fmt"
"reflect"
)
func main() {
type Person struct {
Name string `json:"Name" xml:"Person>FullName"`
Age int `json:"Age" xml:"Person>Age"`
}
var iFace interface{} = Person{
Name: "Test",
Age: 666,
}
fmt.Println("normal: \n" JSONify(iFace))
iFaceType := reflect.TypeOf(iFace)
item := reflect.New(iFaceType)
s := item.Elem()
if s.Kind() == reflect.Struct {
fName := s.FieldByName("Name")
if fName.IsValid() {
// A Value can be changed only if it is
// addressable and was not obtained by
// the use of unexported struct fields.
if fName.CanSet() {
// change value of N
switch fName.Kind() {
case reflect.String:
fName.SetString("reflectedNameValue")
fmt.Println("Name was set to reflectedNameValue")
}
}
}
fAge := s.FieldByName("Age")
if fAge.IsValid() {
// A Value can be changed only if it is
// addressable and was not obtained by
// the use of unexported struct fields.
if fAge.CanSet() {
// change value of N
switch fAge.Kind() {
case reflect.Int:
x := int64(42)
if !fAge.OverflowInt(x) {
fAge.SetInt(x)
fmt.Println("Age was set to", x)
}
}
}
}
}
fmt.Println("reflected: \n" JSONify(item))
}
func JSONify(v interface{}) string {
var bytes []byte
bytes, _ = json.MarshalIndent(v, "", "\t")
return string(bytes)
}
uj5u.com熱心網友回復:
你item的型別是reflect.Value。您必須呼叫Value.Interface()以獲取包含在其中的值:
fmt.Println("reflected: \n" JSONify(item.Interface()))
通過此更改,輸出將是(在Go Playground上嘗試):
normal:
{
"Name": "Test",
"Age": 666
}
Name was set to reflectedNameValue
Age was set to 42
reflected:
{
"Name": "reflectedNameValue",
"Age": 42
}
reflect.Value本身也是一個結構體,但顯然試圖編組它與編組Person結構體值不同。reflect.Value不實作將包裝的資料編組為 JSON。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/373122.html
上一篇:如何將字串的第一個字母大寫
