10 go
我有以下内容:
package main
import (
"encoding/json"
"fmt"
"os"
"reflect"
)
type User struct {
ID int64 `json:"id"`
Name string `json:"first"` // want to change this to `json:"name"`
tag string `json:"-"`
Another
}
type Another struct {
Address string `json:"address"`
}
func (u *User) MarshalJSON() ([]byte, error) {
value := reflect.ValueOf(*u)
for i := 0; i < value.NumField(); i++ {
tag := value.Type().Field(i).Tag.Get("json")
field := value.Field(i)
fmt.Println(tag, field)
}
return json.Marshal(u)
}
func main() {
anoth := Another{"123 Jennings Street"}
_ = json.NewEncoder(os.Stdout).Encode(
&User{1, "Ken Jennings", "name",
anoth},
)
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试对结构进行json编码,但在此之前我需要更改json密钥...例如,最终的json应该如下所示:
{"id": 1, "name": "Ken Jennings", "address": "123 Jennings Street"}
Run Code Online (Sandbox Code Playgroud)
我注意到value.Type().Field(i).Tag.Get("json")的方法,但是没有setter方法.为什么?以及如何获得所需的json输出.
另外,如何遍历所有字段,包括嵌入式结构另一个?
Kav*_*ian 11
在Go 1.8中,您可以使用更简单的解决方案.这段代码:
func main() {
anoth := Another{"123 Jennings Street"}
_ = json.NewEncoder(os.Stdout).Encode(
&User{1, "Ken Jennings", "name",
anoth},
)
}
type User struct {
ID int64 `json:"id"`
Name string `json:"first"` // want to change this to `json:"name"`
tag string `json:"-"`
Another
}
type Another struct {
Address string `json:"address"`
}
func (u *User) MarshalJSON() ([]byte, error) {
type alias struct {
ID int64 `json:"id"`
Name string `json:"name"`
tag string `json:"-"`
Another
}
var a alias = alias(*u)
return json.Marshal(&a)
}
Run Code Online (Sandbox Code Playgroud)
会给我们:
{"id":1,"name":"Ken Jennings","address":"123 Jennings Street"}
Run Code Online (Sandbox Code Playgroud)
这个解决方案可以通过以下事实实现:在Go 1.8中,您可以为结构分配相同但结构不同的结构.如您所见,type alias与字段具有相同的字段,User但具有不同的标记.
它是kludgy,但是如果你可以将结构包装在另一个结构中,并使用新结构进行编码,那么你可以:
interface{}以获取地图从而:
type MyUser struct {
U User
}
func (u MyUser) MarshalJSON() ([]byte, error) {
// encode the original
m, _ := json.Marshal(u.U)
// decode it back to get a map
var a interface{}
json.Unmarshal(m, &a)
b := a.(map[string]interface{})
// Replace the map key
b["name"] = b["first"]
delete(b, "first")
// Return encoding of the map
return json.Marshal(b)
}
Run Code Online (Sandbox Code Playgroud)
在操场上:https://play.golang.org/p/TabSga4i17
小智 6
您可以使用reflect.StructOf和reflect.Value.Convert函数创建一个带有新标签名称的结构副本
https://play.golang.org/p/zJ2GLreYpl0
func (u *User) MarshalJSON() ([]byte, error) {
value := reflect.ValueOf(*u)
t := value.Type()
sf := make([]reflect.StructField, 0)
for i := 0; i < t.NumField(); i++ {
fmt.Println(t.Field(i).Tag)
sf = append(sf, t.Field(i))
if t.Field(i).Name == "Name" {
sf[i].Tag = `json:"name"`
}
}
newType := reflect.StructOf(sf)
newValue := value.Convert(newType)
return json.Marshal(newValue.Interface())
}
Run Code Online (Sandbox Code Playgroud)