结构体内的结构体的映射类型为map[string]struct。

huangapple go评论78阅读模式
英文:

map[string] struct inside struct

问题

我有一个看起来像这样的JSON文件:

{
"jailbreaks": [
{
"jailbroken": false,
"name": "",
"version": "",
"url": "",
"anleitung": [],
"ios": {
"start": "10.2.1"
},
"caveats": "",
"platforms": []
},
{
"jailbroken": true,
"name": "Yalu102",
"version": "beta 6",
"url": "https://domain-dl.tld",
"anleitung": [
{ "blog": "title", "link": "http://domain.tld/" },
{ "blog": "Test", "link": "http://google.at" }
],
"ios": {
"start": "10.2"
},
"caveats": "some text here",
"platforms": [
"Windows",
"OS X",
"Linux"
]
}
]
}

我创建的用于处理的对象如下所示:

type Jailbreak struct {
Jailbroken bool json:"jailbroken"
Name string json:"name"
Version string json:"version"
URL string json:"url"
Anleitung map[string]struct {
Name string json:"blog"
Link string json:"link"
} json:"anleitung"

Firmwares struct {
    Start string `json:"start"`
    End   string `json:"end"`
} `json:"ios"`

Platforms []string `json:"platforms"`
Caveats   string   `json:"caveats"`

}

当我想构建我的Go程序时,我收到一个错误,说无法读取JSON文件。但是,一旦我删除了map[string]struct,我就可以编译和运行程序而没有任何错误,一切正常工作。我是在搞错了什么,还是我的JSON文件中有错误?

英文:

I have a JSON file that looks like this:

{
  "jailbreaks": [
    {
      "jailbroken": false,
      "name": "",
      "version": "",
      "url": "",
      "anleitung": [],
      "ios": {
        "start": "10.2.1"
      },
      "caveats": "",
      "platforms": []
    },
    {
      "jailbroken": true,
      "name": "Yalu102",
      "version": "beta 6",
      "url": "https://domain-dl.tld",
      "anleitung": [
        { "blog": "title", "link": "http://domain.tld/" },
        { "blog": "Test", "link": "http://google.at" }
      ],
      "ios": {
        "start": "10.2"
      },
      "caveats": "some text here",
      "platforms": [
        "Windows",
        "OS X",
        "Linux"
      ]
    },

And I create the object to work with like this:

type Jailbreak struct {
	Jailbroken bool   `json:"jailbroken"`
	Name       string `json:"name"`
	Version    string `json:"version"`
	URL        string `json:"url"`
	Anleitung  map[string]struct {
		Name string `json:"blog"`
		Link string `json:"link"`
	} `json:"anleitung"`

	Firmwares struct {
		Start string `json:"start"`
		End   string `json:"end"`
	} `json:"ios"`

	Platforms []string `json:"platforms"`
	Caveats   string   `json:"caveats"`
}

When I want to build my go program I get an error, that the JSON file cannot be read. But as soon as I delete the map[string]struct I can compile and run the program without any error and everything works fine.
Am I messing around with something or is there an error in my JSON file?

答案1

得分: 1

提供的JSON不是有效的(因为数组没有闭合的],顶层的JSON对象也缺少另一个闭合的}),所以让我们假设它是这样的:

{
  "jailbreaks": [
    {
      "jailbroken": false,
      "name": "",
      "version": "",
      "url": "",
      "anleitung": [],
      "ios": {
        "start": "10.2.1",
        "end": ""
      },
      "platforms": [],
      "caveats": ""
    },
    {
      "jailbroken": true,
      "name": "Yalu102",
      "version": "beta 6",
      "url": "https://domain-dl.tld",
      "anleitung": [
        {
          "blog": "title",
          "link": "http://domain.tld/"
        },
        {
          "blog": "Test",
          "link": "http://google.at"
        }
      ],
      "ios": {
        "start": "10.2",
        "end": ""
      },
      "platforms": [
        "Windows",
        "OS X",
        "Linux"
      ],
      "caveats": "some text here"
    }
  ]
}

数据结构Jailbreaks(第一个)可以正确地将其编组/解组为此JSON:

type Jailbreaks struct {
    List []Jailbreak `json:"jailbreaks"`
}

type Jailbreak struct {
    Jailbroken bool   `json:"jailbroken"`
    Name       string `json:"name"`
    Version    string `json:"version"`
    URL        string `json:"url"`
    Anleitung  []struct {
        Name string `json:"blog"`
        Link string `json:"link"`
    } `json:"anleitung"`

    Firmwares struct {
        Start string `json:"start"`
        End   string `json:"end"`
    } `json:"ios"`

    Platforms []string `json:"platforms"`
    Caveats   string   `json:"caveats"`
}

如你所见,Anleitung 被声明为一个切片(而不是映射)。

英文:

The json provided is not valid (as the array does not have a closing ] and the top level json object lacks another closing }) so let's assume it's like:

{
  "jailbreaks": [
    {
      "jailbroken": false,
      "name": "",
      "version": "",
      "url": "",
      "anleitung": [],
      "ios": {
        "start": "10.2.1",
        "end": ""
      },
      "platforms": [],
      "caveats": ""
    },
    {
      "jailbroken": true,
      "name": "Yalu102",
      "version": "beta 6",
      "url": "https://domain-dl.tld",
      "anleitung": [
        {
          "blog": "title",
          "link": "http://domain.tld/"
        },
        {
          "blog": "Test",
          "link": "http://google.at"
        }
      ],
      "ios": {
        "start": "10.2",
        "end": ""
      },
      "platforms": [
        "Windows",
        "OS X",
        "Linux"
      ],
      "caveats": "some text here"
    }
  ]
}

The data structure Jailbreaks (first one), marshals-to/unmarshals-from this json properly:

type Jailbreaks struct {
	List []Jailbreak `json:"jailbreaks"`
}

type Jailbreak struct {
	Jailbroken bool   `json:"jailbroken"`
	Name       string `json:"name"`
	Version    string `json:"version"`
	URL        string `json:"url"`
	Anleitung  []struct {
		Name string `json:"blog"`
		Link string `json:"link"`
	} `json:"anleitung"`

	Firmwares struct {
		Start string `json:"start"`
		End   string `json:"end"`
	} `json:"ios"`

	Platforms []string `json:"platforms"`
	Caveats   string   `json:"caveats"`
}

As you see Anleitung is declared as a slice (not a map).

答案2

得分: -1

在JSON中,当你的"anleitung"为空时,可以使用omitempty标志来消除它。但要注意,当这种情况发生时,你的Jailbreak结构体将没有一个"anleitung"字段。

将你的map的json标志更改为:

Anleitung   map[string]struct {
    Name string `json:"blog"`
    Link string `json:"link"`
} `json:"anleitung,omitempty"`

选项2:

我猜你也可以使用Anleitung map[string]interface{},但这更适用于"保存字符串到任意数据类型的映射"。在你的情况下,数据并不是任意的,而是空的。而且看起来这只是暂时的。

我会选择选项1,然后在访问之前检查我的结构体是否包含任何Anleitung数据。

英文:

Use omitempty flag for when your "anleitung" is empty in JSON to be consumed. Beware though, when that is the case, your Jailbreak struct won't have an "anleitung" field.

Change your map's json flag to to;

Anleitung   map[string]struct {
	Name string `json:"blog"`
	Link string `json:"link"`
} `json:"anleitung,omitempty"`

Option 2;

I guess you could also use Anleitung map[string]interface{} but that is better for "holding a map of strings to arbitrary data types". In your case the data is not arbitrary but rather, empty I guess. And looks like that is just temporary.

I'd go for option 1, then I'd check if my struct contains any Anleitung data or not before accessing it.

huangapple
  • 本文由 发表于 2017年2月22日 06:03:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/42378878.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定