• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    golang MarshalJson的实现

    发布者: 涵韵3588 | 发布时间: 2025-8-14 07:42| 查看数: 24| 评论数: 0|帖子模式

    在 Go 语言中,
    1. MarshalJSON
    复制代码
    是一个接口方法,允许自定义类型在进行 JSON 编码时提供自定义的序列化逻辑。通过实现
    1. MarshalJSON
    复制代码
    方法,你可以控制结构体或其他类型在转换为 JSON 时的表现。

    基本用法

    当你想要自定义某个类型的 JSON 表现时,可以实现
    1. json.Marshaler
    复制代码
    接口,该接口只包含一个方法
    1. MarshalJSON
    复制代码
    。实现该方法后,使用
    1. json.Marshal
    复制代码
    函数时会自动调用你定义的
    1. MarshalJSON
    复制代码
    方法。

    示例

    以下是一个示例,展示如何自定义结构体的 JSON 序列化:
    1. package main

    2. import (
    3.     "encoding/json"
    4.     "fmt"
    5. )

    6. // 定义一个结构体
    7. type User struct {
    8.     Name  string
    9.     Age   int
    10.     Email string
    11. }

    12. // 为 User 实现 MarshalJSON 方法
    13. func (u User) MarshalJSON() ([]byte, error) {
    14.     // 自定义 JSON 输出格式
    15.     return json.Marshal(struct {
    16.         FullName string `json:"name"`
    17.         Age      int    `json:"age"`
    18.         Email    string `json:"email_address"`
    19.     }{
    20.         FullName: u.Name,
    21.         Age:      u.Age,
    22.         Email:    u.Email,
    23.     })
    24. }

    25. func main() {
    26.     user := User{Name: "Alice", Age: 30, Email: "alice@example.com"}

    27.     // Marshal 用户对象为 JSON
    28.     jsonData, err := json.Marshal(user)
    29.     if err != nil {
    30.         fmt.Println("Error marshaling to JSON:", err)
    31.         return
    32.     }

    33.     fmt.Println(string(jsonData)) // 输出: {"name":"Alice","age":30,"email_address":"alice@example.com"}
    34. }
    复制代码
    解释


    • 定义结构体:我们定义了一个
      1. User
      复制代码
      结构体,包含
      1. Name
      复制代码
      1. Age
      复制代码
      1. Email
      复制代码
      字段。
    • 实现
      1. MarshalJSON
      复制代码
      方法:我们为
      1. User
      复制代码
      结构体实现了
      1. MarshalJSON
      复制代码
      方法。在这个方法中,我们自定义了 JSON 输出格式。
    • 自定义输出:在
      1. MarshalJSON
      复制代码
      方法中,我们使用匿名结构体来定义最终的 JSON 格式。
    • 使用
      1. json.Marshal
      复制代码
      :在
      1. main
      复制代码
      函数中,我们创建了一个
      1. User
      复制代码
      实例,并使用
      1. json.Marshal
      复制代码
      将其转换为 JSON 字符串。

    注意事项


    • 错误处理
      1. MarshalJSON
      复制代码
      方法应返回
      1. error
      复制代码
      ,以便在序列化过程中可以处理潜在的错误。
    • 递归调用:在
      1. MarshalJSON
      复制代码
      方法中,如果调用
      1. json.Marshal
      复制代码
      ,需要确保所处理的结构体不会递归调用自身的
      1. MarshalJSON
      复制代码
      方法。
    Marshal函数将会递归遍历整个对象,依次按成员类型对这个对象进行编码。
    类型转换规则如下:

    • bool类型:转换为JSON的Boolean
    • 整数、浮点数等数值类型: 转换为JSON的Number
    • string类型: 转换为JSON的字符串(带""引号)
    • struct类型:转换为JSON的Object,再根据各个成员的类型递归打包
    • 数组或切片类型: 转换为JSON的Array
    • []byte类型: 会先进行base64编码然后转换为JSON字符串
    • map类型:转换为JSON的Object,key必须是string
    • interface{}类型: 按照内部的实际类型进行转换
    • nil类型: 转为JSON的null
    • channel,func等类型: 会返回UnsupportedTypeError
    从golang到json:
    golangjsonboolBooleanint、float等数字NumberstringString[]byte(base64编码)StringstructObject,再递归打包array/sliceArraymapObjectinterface{}按实际类型转换nilnullchannel,funcUnsupportedTypeError从json到golang:
    jsongolangBooleanboolNumberfloat64StringstringArray[]interface{}Objectmap[string]interface{}nullnil
    避坑

    json.marshal使用不当,会存在base64编码问题问题出现在:
    1. []byte 在json.marshal时会进行base64 encoding处理
    复制代码
    解决办法:使用json.RawMessage
    1. json.RawMessage
    复制代码
    其实就是
    1. []byte
    复制代码
    类型的重定义。可以进行强制类型转换。
    现在有这么一种场景,结构体中的其中一个字段的格式是未知的:
    1. type Command struct {  
    2.     ID   int  
    3.     Cmd  string  
    4.     Args *json.RawMessage  
    5. }  
    复制代码
    使用
    1. json.RawMessage
    复制代码
    的话,Args字段在Unmarshal时不会被解析,直接将字节数据赋值给Args。我们可以能先解包第一层的JSON数据,然后根据Cmd的值,再确定Args的具体类型进行第二次Unmarshal。
    1. 注意:一定要使用指针类型[code]*json.RawMessage
    复制代码
    ,否则在Args会被认为是[]byte类型,在打包时会被打包成base64编码的字符串。[/code]使用interface{}, interface{}类型在Unmarshal时,会自动将JSON转换为对应的数据类型:
    1. JSON的boolean: 转换为boolJSON的数值: 转换为float64JSON的字符串: 转换为stringJSON的Array: 转换为[]interface{}JSON的Object: 转换为map[string]interface{}JSON的null: 转换为nil
    复制代码
    需要注意的有两个:

    • 一是所有的JSON数值自动转换为float64类型,使用时需要再手动转换为需要的int,int64等类型。
    • 二是JSON的object自动转换为
      1. map[string]interface{}
      复制代码
      类型,访问时直接用JSON Object的字段名作为key进行访问。在不知道JSON数据的格式时,可以使用interface{}。
    自定义类型:如果希望自己定义对象的打包解包方式,可以实现以下的接口:
    1. type Marshaler interface {  
    2.     MarshalJSON() ([]byte, error)  
    3. }  
    4. type Unmarshaler interface {  
    5.     UnmarshalJSON([]byte) error  
    6. }  
    复制代码
    实现该接口的对象需要将自己的数据打包和解包。如果实现了该接口,json在打包解包时则会调用自定义的方法,不再对该对象进行其他处理。

    总结

    通过实现
    1. MarshalJSON
    复制代码
    方法,可以为 Go 的自定义类型提供灵活的 JSON 序列化控制。这使得在与 JSON 数据交互时,可以更好地控制数据的结构和格式。
    到此这篇关于golang MarshalJson的实现的文章就介绍到这了,更多相关golang MarshalJson内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    来源:互联网
    免责声明:如果侵犯了您的权益,请联系站长(1277306191@qq.com),我们会及时删除侵权内容,谢谢合作!

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表