You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang中如何将[]byte切片转换为可操作的JSON?

Go中解析多维JSON的基础方法

首先纠正你代码里的JSON语法错误:原JSON中track数组的第一个对象里,artist字段结尾多了个逗号,导致结构非法,修正后的JSON如下:

bytt := []byte(`{"tracks":{"track":[{"name":"Yellow","duration":"276","artist":{"name":"coldplay"}},{"name":"red","duration":"345","artist":{"name":"somename"}}]}}`)

Go是强类型语言,没有PHP/JS那种动态多维数组,要解析并操作JSON,主要有两种常用方式:

1. 结构体映射(推荐,类型安全)

先定义和JSON结构完全匹配的结构体,再用encoding/json包的Unmarshal方法解析,操作时直接访问结构体字段即可。

示例代码

package main

import (
	"encoding/json"
	"fmt"
)

// 定义对应JSON结构的结构体
type Artist struct {
	Name string `json:"name"` // json标签指定与JSON字段的映射关系
}

type Track struct {
	Name     string `json:"name"`
	Duration string `json:"duration"`
	Artist   Artist `json:"artist"`
}

type MusicResponse struct {
	Tracks struct {
		TrackList []Track `json:"track"`
	} `json:"tracks"`
}

func main() {
	bytt := []byte(`{"tracks":{"track":[{"name":"Yellow","duration":"276","artist":{"name":"coldplay"}},{"name":"red","duration":"345","artist":{"name":"somename"}}]}}`)

	var resp MusicResponse
	// 将[]byte解析到结构体指针
	err := json.Unmarshal(bytt, &resp)
	if err != nil {
		fmt.Println("JSON解析失败:", err)
		return
	}

	// 遍历歌曲列表
	for idx, track := range resp.Tracks.TrackList {
		fmt.Printf("第%d首歌:\n", idx+1)
		fmt.Printf("  名称:%s\n", track.Name)
		fmt.Printf("  时长:%s秒\n", track.Duration)
		fmt.Printf("  歌手:%s\n\n", track.Artist.Name)
	}
}

关键说明

  • 结构体字段必须首字母大写,否则encoding/json包无法访问(Go中只有导出字段能被外部包读取)。
  • json:"xxx"标签用来关联JSON中的小写字段和结构体的大写字段,必须和JSON字段名完全一致。

2. 动态解析(map[string]interface{})

如果JSON结构不确定,或者不想定义结构体,可以用map[string]interface{}类型解析,类似PHP/JS的关联数组,但需要手动做类型断言才能访问具体值。

示例代码

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	bytt := []byte(`{"tracks":{"track":[{"name":"Yellow","duration":"276","artist":{"name":"coldplay"}},{"name":"red","duration":"345","artist":{"name":"somename"}}]}}`)

	var data map[string]interface{}
	err := json.Unmarshal(bytt, &data)
	if err != nil {
		fmt.Println("JSON解析失败:", err)
		return
	}

	// 逐层类型断言并访问
	tracks := data["tracks"].(map[string]interface{})
	trackList := tracks["track"].([]interface{})

	for _, item := range trackList {
		track := item.(map[string]interface{})
		// 断言为string类型,失败会panic,生产环境可加ok判断
		name := track["name"].(string)
		duration := track["duration"].(string)
		artist := track["artist"].(map[string]interface{})
		artistName := artist["name"].(string)

		fmt.Printf("歌曲:%s | 时长:%s | 歌手:%s\n", name, duration, artistName)
	}
}

关键说明

  • interface{}是Go的空接口,可以存储任意类型的值,解析后需要用.(类型)断言成具体类型才能操作。
  • 生产环境建议用val, ok := obj.(类型)的安全断言方式,避免panic:
    artist, ok := track["artist"].(map[string]interface{})
    if !ok {
        fmt.Println("artist字段类型错误")
        continue
    }
    

内容的提问来源于stack exchange,提问作者black

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 10:13:32