英文:
Override Go JSON tag values at runtime
问题
我在我的Web应用程序中使用"encoding/json"有以下的结构体:
type CourseAssignment struct {
Semester int `json:"semester" xml:"semester"`
Lecture Lecture `json:"-" xml:"-"`
Cos Cos `json:"-" xml:"-"`
Links map[string][]Link `json:"links,omitempty" xml:"links,omitempty"`
}
Lecture和Cos本身是复杂的结构体,我不希望它们被包含在我的序列化JSON中,所以我通过设置json:"-"
来指示。
这个方法完美地运行。
在运行时,我如何在需要的时候覆盖这种行为,而不编写自己的序列化代码?
我的解决方案如下:
func (r *CourseAssignment) Expand(depth int) CourseAssignment {
if depth <= 0 {
return *r
}
tmp := *r
tmp.LectureEx = tmp.Lecture
tmp.CosEx = tmp.Cos
tmp.Links = nil
return tmp
}
type CourseAssignment struct {
Semester int `json:"semester" xml:"semester"`
Lecture *Lecture `json:"-" xml:"-"`
Cos *Cos `json:"-" xml:"-"`
Links map[string][]Link `json:"links,omitempty" xml:"links,omitempty"`
LectureEx *Lecture `json:"lecture,omitempty" xml:"lecture,omitempty"`
CosEx *Cos `json:"course_of_study,omitempty" xml:"course_of_study,omitempty"`
}
当我想要包含这些字段时,我使用Expand
创建对象的副本,该副本填充了包含相同引用但在序列化中显示的字段。
英文:
I have the following struct in in my Web Application using "encoding/json"
type CourseAssignment struct {
Semester int `json:"semester" xml:"semester"`
Lecture Lecture `json:"-" xml:"-"`
Cos Cos `json:"-" xml:"-"`
Links map[string][]Link `json:"links,omitempty" xml:"links,omitempty"`
}
Lecture and Cos are complex structs themselves that i dont want to be included in my serialized json which i indicate by setting json:"-"
This works perfectly.
How do I override that behavior on demand during runtime, without writing my own Serialization code?
My Own Solution:
func (r *CourseAssignment) Expand(depth int) CourseAssignment {
if depth <= 0 {
return *r
}
tmp := *r
tmp.LectureEx = tmp.Lecture
tmp.CosEx = tmp.Cos
tmp.Links = nil
return tmp
}
type CourseAssignment struct {
Semester int `json:"semester" xml:"semester"`
Lecture *Lecture `json:"-" xml:"-"`
Cos *Cos `json:"-" xml:"-"`
Links map[string][]Link `json:"links,omitempty" xml:"links,omitempty"`
LectureEx *Lecture `json:"lecture,omitempty" xml:"lecture,omitempty"`
CosEx *Cos `json:"course_of_study,omitempty" xml:"course_of_study,omitempty"`
}
When I want to include the fields, I create a Copy of the Object using Expand
that fills fields that contain the same references but show up in the serialization.
答案1
得分: 4
你可以使用reflect
包中的StructTag
来读取/获取结构体标签的值:
package main
import (
"fmt"
"reflect"
)
type CourseAssignment struct {
Semester int `json:"semester" xml:"semester"`
}
func main() {
ca := CourseAssignment{}
st := reflect.TypeOf(ca)
field := st.Field(0)
fmt.Println(field.Tag.Get("json"))
}
标准库中没有提供直接修改结构体标签字段的方法。
然而,有一些开源库可以实现这一功能,比如Retag。
英文:
You can read/get struct tag values using StructTag
from reflect
package:
package main
import (
"fmt"
"reflect"
)
type CourseAssignment struct {
Semester int `json:"semester" xml:"semester"`
}
func main() {
ca := CourseAssignment{}
st := reflect.TypeOf(ca)
field := st.Field(0)
fmt.Println(field.Tag.Get("json"))
}
There is no method to change a struct tag field in the standard library.
However, there are open-source libraries that do exactly that, like Retag.
答案2
得分: 0
在类似情况下,我通常会将这些字段设置为omitempty
,然后在不希望它们包含在JSON中的情况下将其置为空:
type CourseAssignment struct {
Semester int `json:"semester" xml:"semester"`
Lecture *Lecture `json:"lecture,omitempty" xml:"-"`
Cos *Cos `json:"cos,omitempty" xml:"-"`
Links map[string][]Link `json:"links,omitempty" xml:"links,omitempty"`
}
// 不包含Lecture/Cos进行序列化:
aCourseAssignment.Lecture = nil
aCourseAssignment.Cos = nil
thing, err := json.Marshal(aCourseAssignment)
以上是代码的翻译部分。
英文:
What I've done in similar cases is to set these kinds of fields to omitempty
, and then empty them before serializing in the cases where I don't want them included in JSON:
type CourseAssignment struct {
Semester int `json:"semester" xml:"semester"`
Lecture *Lecture `json:"lecture,omitempty" xml:"-"`
Cos *Cos `json:"cos,omitempty" xml:"-"`
Links map[string][]Link `json:"links,omitempty" xml:"links,omitempty"`
}
// Want to serialize without including Lecture/Cos:
aCourseAssignment.Lecture = nil
aCourseAssignment.Cos = nil
thing,err := json.Marshal(aCourseAssignment)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论