实现MarshalJSON() ([]byte, error)
方法 ,序列化后可以把原来的枚举数转化为枚举数对应的字符串
实现UnmarshalJSON([]byte) error
方法,可以把byte中的枚举的字符串转化为对应枚举字符串的枚举数
实现String() string
方法,方便按照我们想看的方式打印出来fmt.Println()
,类似与python的__str__
和__repr__
package main_test
import (
"errors"
"fmt"
"strings"
"testing"
"github.com/bytedance/sonic"
)
type A struct {
B B
C string
}
type B int8
const (
UP B = iota
DOWN
PENDING
)
var (
StatusValueMap = map[B]string{
UP: "up",
DOWN: "down",
PENDING: "pending",
}
)
//实现 MarshalJSON 对枚举值进行转化
func (b B) MarshalJSON() ([]byte, error) {
if v, ok := StatusValueMap[b]; ok {
return []byte(`"` + v + `"`), nil
}
return nil, errors.New("枚举未定义")
}
//实现 UnmarshalJSON 对枚举值进行转化
func (b *B) UnmarshalJSON(data []byte) error {
s := strings.Trim(string(data), `"`)
for k, v := range StatusValueMap {
if v == s {
b = &k
return nil
}
}
return errors.New("未转化成功")
}
//实现String方法,方便打印查看
func (b B) String() string {
return StatusValueMap[b]
}
func TestAbc(t *testing.T) {
a := A{
B: UP,
C: "111",
}
//json标准库和sonic第三方库都可以
// s, err := json.Marshal(a)
s, err := sonic.Marshal(a)
if err != nil {
panic(err)
}
fmt.Println(string(s)) //{"B":"up","C":"111"} 可以看到,已经将数字序列化成数字对应的字符串
b := &A{}
// err = json.Unmarshal(s, b)
err = sonic.Unmarshal(s, b)
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", b) //&{B:up C:111} //已经将字符串反序列化为数字,这里显示up是因为实现了String()方法,可以看到,下面是等于0的
fmt.Println(b.B == 0) //true
}
遇到的坑
直接应用项为枚举时
如果结构体是如下这种
type A struct {
Title string `json:"title" gorm:"column:title;uniqueIndex:idx_title" validate:"required"`
Author string `json:"author" gorm:"column:author;not null" validate:"required"`
Summary string `json:"summary" gorm:"column:summary;not null"`
Content string `json:"content" gorm:"column:content"`
//这里省略了后面跟的Status,是可以正常使用的,但是如果实现了序列化的三个方法,会导致整个结构体只有status被序列化,其他的被忽略
Status `json:"status" gorm:"column:status;not null"`
}
// Status Status枚举
type Status int8
const (
DRAFT Status = 1 + iota
PUBLISHED
)
在A机构体中,继承了枚举Status的结构体
这个时候,如果Status实现了序列化的三个方法MarshalJSON()
、UnmarshalJSON()
、String()
则会导致结构体A序列化时,只显示Status序列化的值,而A中的其他项都不会被序列化
正确的继承方法是
type A struct {
Title string `json:"title" gorm:"column:title;uniqueIndex:idx_title" validate:"required"`
Author string `json:"author" gorm:"column:author;not null" validate:"required"`
Summary string `json:"summary" gorm:"column:summary;not null"`
Content string `json:"content" gorm:"column:content"`
//这里需要写清楚,不要省略第二个Status
Status Status `json:"status" gorm:"column:status;not null"`
}
// Status Status枚举
type Status int8
const (
DRAFT Status = 1 + iota
PUBLISHED
)
不要省略Status后跟的Status
标签:Status,string,自定义,column,枚举,json,Go,序列化 From: https://www.cnblogs.com/guangdelw/p/17034046.html