Go语言学习笔记十四(将结构体的数据保存为json格式)

本文介绍了在Go语言中如何将结构体数据序列化为JSON格式,主要涉及json.Marshal()函数的使用,以及自定义的MarshalJson()、WriteAny()、WriteSlice()和WriteStruct()等辅助函数,用于处理不同类型的数据转换,包括字符串、整型、切片和结构体。
摘要由CSDN通过智能技术生成

JSON是一种比较通用的对象文本格式。在Go语言中,结构体数据可以通过系统提示的json.Marshal()函数进行序列化。
下面本文就对序列化数据进行模拟
将结构体序列化为json分为如下几个步骤:
(1) 准备数据结构
(2) 准备要序列化的结构体数据
(3) 调用序列化函数

主函数入口

package main
import (
	"fmt"
	"reflect"
	"bytes"
	"strconv"
)
func main(){
	//创建技能结构体
	type Skill struct {
		Name string
		Level int
	}
	//创建角色结构体
	type Actor struct {
		Name string
		Age int
		Skills []Skill
	}
	//填充角色数据
	a := Actor {
		Name:"wangy"
		Age:28
		Skills: []Skill{{Name:"doctor",Level: 5},{Name: "student",Level: 5},{Name:"wife",Level: 5},},
    }
    if result, ok := MarshalJson(a); err==nil {
    	fmt.Println(result)
    } else {
		fmt.Println(err)
	}
}

这里的MarshalJson()是自己创建的函数将Actor实例化结构体转化成JSON格式,如果转化成功则输出数据,失败则打印错误。
MarshalJson()函数是序列化过程的主函数入口。通过这个函数可以调用不同的子序列化函数满足不同类型数据的转化。该函数传入一个interface{}类型数据,如果转化成功返回数据,失败则返回错误信息。
JSON系列化主函数代码:

func MarshalJson(v interface{}) (string, error) {

	//准备一个缓冲
	var b bytes.Buffer
	//将任意值转化成json并写入缓冲中
	if err := WriteAny(&b,reflect.ValueOf(v));err == nil {
		return b.String(),nil
	} else {
		return "", err
	}	
}

这里首先创建一个缓冲通道b用来写入数据
WriteAny()是自己创建的函数可以做任意值序列化,如果发生错误则返回错误信息。
WriteAny函数代码如下

//将人任意值转化成json格式并写入通道中
func WriteAny(b *bytes.Buffer, value reflect.Value) error {
	//用switch分支处理不同数据的格式转化
	switch value.Kind() {
		case reflect.String:
			//向通道中写入带双引号的字符串
			return b.WriteString(strconv.Quote(value.String()))
		case reflect.Int:
			//将整型转换成字符串并写入到缓冲中
			return b.WriteString(strconv.FormatInt(value.Int(),10))
		case reflect.Slice:
			//写入切片类型数据
			WriteSlice(b, value)
		case reflect.Struct:
			WriteStruct(b,value)
		default:
			//遇到不认识的类型返回错误信息
			return errors.New("unspport kind"+value.Kind().String())
	}
	return nil
}

//对切片序列化代码如下

func WriteSlice(b *bytes.Buffer, value reflect.Value) error {
	//写入切片开始标记
	b,WriterString("[")
	//遍历每个元素
	for i := 0; i < value.Len(); i++ {
		//获取切片元素
		valueSlice := value.Field(i)
		//写入每个切片
		WriteAny(b,valueSlice)
		//除去最后一个元素外每个元素末尾写入逗号
		if i < value.Len()-1 {
			b.WriteString(",")
		}
	}
	//写入切片结束标志
	b.WriteString("]")
	return nil
}

结构体序列化代码如下

//将结构体转化成json格式并写入到通道中
func WriteStruct(b *bytes.Buffer, value reflect.Value) error {
	//获取value类型
	valueType := value.Type()
	//写入结构体左大括号
	b.WriteString("{")
	//遍历结构体所有值
	for i := 0; i < value.NumField(); i++ {
		//获取每个结构体的字段值
		FieldValue := value.Field(i)
		//获取每个字段的类型
		FieldType := valueType.Field(i)
		//写入字段的左双引号
		b.WriteString("/"")
		//写入字段名字
		b.WriteString(valueType.Name())
		//写入字段的右双引号
		b.WriteString("/":")
		//写入每个字段值
		WriteAny(b,FieldValue)
		//每个字段后面跟一个逗号
		if i < value.NumField()-1{
			s.WriteString(",")
		}
	}
	//写入结构体的右大括号
	s.WriteStirng("}")
	return nil
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值