首页 > 其他分享 >Go 自定义序列化

Go 自定义序列化

时间:2023-01-08 06:44:48浏览次数:44  
标签:Status string 自定义 column 枚举 json Go 序列化

实现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

相关文章

  • Go结构体数据校验
    github.com/go-playground/validator范围约束对于字符串、切片、数组和map,约束其长度。len=10,min=6,max=10,gt=10。对于数值,约束其取值。min,max,eq,ne,g......
  • Go实现String方法
    给结构体实现String()sting方法,方便按照我们想看的方式打印出来fmt.Println(),类似与python的__str__和__repr__packagemain_testimport( "fmt" "github.com/byteda......
  • .NET Core读取配置文件 实体类映射获取配置文件中参数 默认情况下读取配置Configura
    .NETCore读取配置文件https://www.jb51.net/article/254440.htm1.说明默认情况下读取配置Configuration的默认优先级:ConfigureAppConfiguration(自定义读取)>Command......
  • Vue自定义事件原理
    自定义事件的基本用法<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"/><metaname="viewport"content="width=device-width,initial-sca......
  • Go语言学习day2
    1.go的结构体没有构造函数,但是可以自己实现一个。由于值拷贝的开销比较大,所以返回的是结构体指针类型packagemainimport"fmt"typepersonstruct{ name,citystr......
  • go in action学习,go语法一些特殊点
    1.如果接口类型只包含一个方法,那么这个类型的名字以er结尾。如果接口类型内部声明了多个方法,其名字需要与其行为关联。2.如果要让一个用户定义的类型实现一个接口,这个用......
  • 07-自定义对象
    自定义对象基本概念在js中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。对象是由属性和方法组成的。属性:事物的特征,在对象......
  • 适合编程初学者的开源项目:小游戏2048(Go语言版)
    目标为编程初学者打造入门学习项目,使用各种主流编程语言来实现。2048游戏规则一共16个单元格,初始时由2或者4构成。1、手指向一个方向滑动,所有格子会向那个方向运动。2......
  • .net core Kestrel宿主服务器自定义监听端口配置
    .netcoreKestrel宿主服务器自定义监听端口配置http://t.zoukankan.com/williamwsj-p-9645095.html.netcoreKestrel宿主服务器自定义监听端口配置在.netcore的w......
  • asp.net core部署时自定义监听端口,提高部署的灵活性
    asp.netcore部署时自定义监听端口,提高部署的灵活性原文连接:http://www.manongjc.com/detail/51-deiojnabsarikgh.html用的是命令参数的方式,简单写的,代码很low,不喜勿喷!......