如何在 Go 中序列化混合类型 JSON 数组

来源:网站主作者:石川澪头衔:网络博主
导读:本期聚焦于小伙伴创作的《如何在 Go 中序列化混合类型 JSON 数组》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何在 Go 中序列化混合类型 JSON 数组》有用,将其分享出去将是对创作者最好的鼓励。

在Go语言开发过程中,经常会遇到需要把数据序列化为JSON格式的场景,其中混合类型JSON数组的序列化是很多开发者容易遇到问题的地方。混合类型JSON数组指的是数组中包含字符串、数字、布尔值、对象、数组等多种不同数据类型的元素,比如[1, "hello", true, {"name": "test"}, [1,2]]这样的结构。

如何在 Go 中序列化混合类型 JSON 数组

使用原生interface{}类型实现序列化

Go的encoding/json标准库支持将[]interface{}类型序列化为JSON数组,因为interface{}可以接收任意类型的值,正好匹配混合类型数组的需求。我们可以先构造一个[]interface{}切片,往里面添加不同类型的元素,再调用json.Marshal方法完成序列化。

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	// 构造混合类型数组
	mixedArr := []interface{}{
		1,
		"hello world",
		true,
		map[string]string{"name": "张三", "age": "20"},
		[]int{1, 2, 3},
	}

	// 执行序列化
	data, err := json.Marshal(mixedArr)
	if err != nil {
		fmt.Println("序列化失败:", err)
		return
	}
	// 输出结果
	fmt.Println(string(data))
}

上述代码的输出结果为[1,"hello world",true,{"age":"20","name":"张三"},[1,2,3]],完全符合混合类型JSON数组的预期格式。

自定义类型处理复杂混合场景

如果混合数组中的元素有固定的结构,或者需要自定义序列化逻辑,可以定义自定义类型并实现json.Marshaler接口。比如我们需要序列化一个包含用户信息和状态标识的混合数组,其中用户信息是结构体,状态是布尔值。

package main

import (
	"encoding/json"
	"fmt"
)

// 定义用户结构体
type User struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

// 自定义混合数组元素类型
type MixedItem struct {
	User  *User
	IsVip bool
}

// 实现MarshalJSON方法
func (m MixedItem) MarshalJSON() ([]byte, error) {
	// 构造临时的混合数组
	arr := []interface{}{
		m.User,
		m.IsVip,
	}
	return json.Marshal(arr)
}

func main() {
	items := []MixedItem{
		{User: &User{Name: "李四", Age: 25}, IsVip: true},
		{User: &User{Name: "王五", Age: 30}, IsVip: false},
	}

	data, err := json.Marshal(items)
	if err != nil {
		fmt.Println("序列化失败:", err)
		return
	}
	fmt.Println(string(data))
}

运行上述代码会输出[{"name":"李四","age":25},true,{"name":"王五","age":30},false],实现了自定义结构的混合类型数组序列化。

注意事项

  • 使用interface{}类型时,数值类型默认会被序列化为float64,如果需要保持整数类型,可以在构造切片时明确使用int等类型,或者在序列化后做类型处理。
  • 如果混合数组中包含指针类型,要确保指针不为空,否则序列化时会出现异常结果。
  • 自定义序列化逻辑时,要注意避免循环引用,否则会导致序列化陷入死循环。

常见问题解答

序列化后数字变成浮点数怎么办

这是因为interface{}接收数字时默认会推断为float64类型,可以在构造数组时显式使用json.Number类型,示例如下:

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	mixedArr := []interface{}{
		json.Number("123"),
		"test",
	}
	data, _ := json.Marshal(mixedArr)
	fmt.Println(string(data))
}

上述代码输出的数字会保持字符串形式的整数,不会变成浮点数。

如何反序列化混合类型JSON数组

反序列化时同样可以使用[]interface{}接收结果,之后再根据元素的实际类型做类型断言处理,示例如下:

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	jsonStr := `[1, "hello", true]`
	var result []interface{}
	err := json.Unmarshal([]byte(jsonStr), &result)
	if err != nil {
		fmt.Println("反序列化失败:", err)
		return
	}
	for _, v := range result {
		switch val := v.(type) {
		case float64:
			fmt.Printf("数字类型: %vn", val)
		case string:
			fmt.Printf("字符串类型: %vn", val)
		case bool:
			fmt.Printf("布尔类型: %vn", val)
		}
	}
}

GoJSON序列化混合类型数组encoding_json修改时间:2026-07-05 00:51:13

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。