Golang中如何定义无父级的JSON结构体

Golang中如何定义无父级的JSON结构体

{
    "foo":"bar",
    "bar":"foo"
}

如何为这个JSON结构创建结构体/类型?

这是另一个例子:

{ 
    "foo",
    "bar"
}

我知道这可以用map[string]string来解组

但由于某些原因,我需要一个结构体。

有什么方法可以实现这一点吗?

3 回复

抱歉,我之前的提问格式不够规范。

非常感谢,你的代码片段运行得很成功!

更多关于Golang中如何定义无父级的JSON结构体的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你的第一个例子是

type t struct {
  Foo string `json:”foo”`
  Bar string `json:”bar”`
}

你的第二个例子不是有效的 JSON。我不确定你所说的"无括号"是什么意思。

在Go语言中,对于无固定父级字段名称的JSON结构,可以使用map[string]interface{}类型来定义结构体,或者使用带有json:",inline"标签的嵌入字段。以下是具体实现方法:

方法一:使用map[string]interface{}

package main

import (
    "encoding/json"
    "fmt"
)

type DynamicStruct struct {
    Data map[string]interface{} `json:"-"`
}

// 自定义UnmarshalJSON方法
func (d *DynamicStruct) UnmarshalJSON(data []byte) error {
    return json.Unmarshal(data, &d.Data)
}

// 自定义MarshalJSON方法
func (d *DynamicStruct) MarshalJSON() ([]byte, error) {
    return json.Marshal(d.Data)
}

func main() {
    // 示例1:处理键值对JSON
    jsonStr1 := `{"foo":"bar","bar":"foo"}`
    var ds1 DynamicStruct
    json.Unmarshal([]byte(jsonStr1), &ds1)
    fmt.Printf("解析结果: %+v\n", ds1.Data)
    
    // 重新序列化
    output1, _ := json.Marshal(ds1)
    fmt.Printf("序列化结果: %s\n", string(output1))
}

方法二:使用匿名结构体(适用于已知字段)

package main

import (
    "encoding/json"
    "fmt"
)

// 为特定JSON结构定义结构体
type FooBarStruct struct {
    Foo string `json:"foo,omitempty"`
    Bar string `json:"bar,omitempty"`
}

func main() {
    // 示例1处理
    jsonStr1 := `{"foo":"bar","bar":"foo"}`
    var fb1 FooBarStruct
    json.Unmarshal([]byte(jsonStr1), &fb1)
    fmt.Printf("Foo: %s, Bar: %s\n", fb1.Foo, fb1.Bar)
    
    // 示例2处理 - 数组格式需要特殊处理
    jsonStr2 := `["foo","bar"]`
    var arr []string
    json.Unmarshal([]byte(jsonStr2), &arr)
    fmt.Printf("数组结果: %v\n", arr)
}

方法三:通用动态结构体

package main

import (
    "encoding/json"
    "fmt"
)

type JSONData struct {
    content []byte
}

func (j *JSONData) UnmarshalJSON(data []byte) error {
    j.content = make([]byte, len(data))
    copy(j.content, data)
    return nil
}

func (j *JSONData) MarshalJSON() ([]byte, error) {
    return j.content, nil
}

func (j *JSONData) ToMap() (map[string]interface{}, error) {
    var result map[string]interface{}
    err := json.Unmarshal(j.content, &result)
    return result, err
}

func main() {
    jsonStr := `{"foo":"bar","bar":"foo"}`
    var jd JSONData
    json.Unmarshal([]byte(jsonStr), &jd)
    
    data, _ := jd.ToMap()
    fmt.Printf("动态解析: %+v\n", data)
}

对于第二个数组示例 ["foo","bar"],这不是有效的JSON对象,需要使用切片类型:

package main

import (
    "encoding/json"
    "fmt"
)

func main() {
    jsonStr := `["foo","bar"]`
    var arr []string
    json.Unmarshal([]byte(jsonStr), &arr)
    fmt.Printf("数组内容: %v\n", arr)
    
    // 如果需要结构体包装
    type StringArray struct {
        Elements []string `json:"-"`
    }
    
    // 自定义处理逻辑...
}

这些方法提供了处理无固定父级JSON结构的灵活方案,可以根据具体需求选择最适合的实现方式。

回到顶部