Golang中如何创建包含map切片(数组)的JSON结构体

Golang中如何创建包含map切片(数组)的JSON结构体 我正在学习Go语言,并正在构建一个简单的命令行界面工具来发起HTTP请求。我尝试构建一个具有以下结构的JSON请求体,其中的名称值是根据提供的字符串动态创建的。根据输入字符串“joan,john”,JSON看起来像这样:

{
    "reviewers": [
        {"user": {"name": "joan"}},
        {"user": {"name": "john"}}
    ]
}

我搜索了如何构建一个映射切片,并整理了下面的代码,但遇到了编译器错误。我哪里做错了?

type HTTPRequestBody struct {
    Reviewers ReviewersArray `json:"reviewers,omitempty"`
}

type ReviewersArray struct {
    Rs []struct {
        Users User
    }
}

type User struct {
    User Name `json:"user`
}

type Name struct {
    Name string `json:"name`
}

func addReviewers(reviewers string) *ReviewersArray {
    reviewersSplit := strings.Split(reviewers, ",")
    rArray := &ReviewersArray{}
    for _, r := range reviewersSplit {
        u := &User{User: Name{Name: r}}
        // 错误:无法将 u(类型为 *User 的变量)作为 struct{Users User} 值用于 append 的参数
        rArray.Rs = append(rArray.Rs, u)

        // rArray = append(rArray, u)
        // rArray{Rs: append(rArray.Rs, u)},
        // rArray{Rs: append(rArray, u)},
    }
    return rArray
}

func main() {
    testReviewers := "joan,john"

    prReviewers := addReviewers(testReviewers)
    requestBody := &HTTPRequestBody{
        // 错误:无法将 prReviewers(类型为 *ReviewersArray 的变量)作为 ReviewersArray 值用于结构体字面量
        Reviewers: prReviewers,
    }

    jsonData, _ := json.MarshalIndent(requestBody, "", "  ")
    fmt.Println(string(jsonData))
}

更多关于Golang中如何创建包含map切片(数组)的JSON结构体的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

谢谢查尔斯,非常感谢你的回复 😊

更多关于Golang中如何创建包含map切片(数组)的JSON结构体的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


如果使用结构体而不是 map[string]interface{} 对你来说更容易,这里是示例:https://play.golang.org/p/UCt7t3xY8oK

你的代码有几个结构定义和类型匹配问题。以下是修正后的版本:

package main

import (
	"encoding/json"
	"fmt"
	"strings"
)

type HTTPRequestBody struct {
	Reviewers []Reviewer `json:"reviewers,omitempty"`
}

type Reviewer struct {
	User User `json:"user"`
}

type User struct {
	Name string `json:"name"`
}

func addReviewers(reviewers string) []Reviewer {
	reviewersSplit := strings.Split(reviewers, ",")
	var rArray []Reviewer
	
	for _, r := range reviewersSplit {
		reviewer := Reviewer{
			User: User{
				Name: strings.TrimSpace(r),
			},
		}
		rArray = append(rArray, reviewer)
	}
	return rArray
}

func main() {
	testReviewers := "joan,john"
	
	prReviewers := addReviewers(testReviewers)
	requestBody := &HTTPRequestBody{
		Reviewers: prReviewers,
	}
	
	jsonData, _ := json.MarshalIndent(requestBody, "", "  ")
	fmt.Println(string(jsonData))
}

输出结果:

{
  "reviewers": [
    {
      "user": {
        "name": "joan"
      }
    },
    {
      "user": {
        "name": "john"
      }
    }
  ]
}

如果需要更简洁的匿名结构体版本:

package main

import (
	"encoding/json"
	"fmt"
	"strings"
)

type HTTPRequestBody struct {
	Reviewers []struct {
		User struct {
			Name string `json:"name"`
		} `json:"user"`
	} `json:"reviewers,omitempty"`
}

func addReviewers(reviewers string) HTTPRequestBody {
	reviewersSplit := strings.Split(reviewers, ",")
	requestBody := HTTPRequestBody{}
	
	for _, r := range reviewersSplit {
		reviewer := struct {
			User struct {
				Name string `json:"name"`
			} `json:"user"`
		}{
			User: struct {
				Name string `json:"name"`
			}{
				Name: strings.TrimSpace(r),
			},
		}
		requestBody.Reviewers = append(requestBody.Reviewers, reviewer)
	}
	return requestBody
}

func main() {
	testReviewers := "joan,john"
	
	requestBody := addReviewers(testReviewers)
	jsonData, _ := json.MarshalIndent(requestBody, "", "  ")
	fmt.Println(string(jsonData))
}

主要修正点:

  1. 简化了结构体嵌套层级
  2. 直接使用切片类型 []Reviewer 而不是额外的包装结构
  3. 修正了JSON标签的语法错误(缺少闭合引号)
  4. 修复了类型不匹配的问题
回到顶部