英文:
Mapping strings to multiple types for json objects?
问题
我想创建一个可以转换为 JSON 对象的映射,例如:
{
"a": "apple",
"b": 2
}
但是 golang 要求映射必须声明类型,所以我可以有 map[string]string 或 map[string]int。我如何创建上述的 JSON 对象?
注意:在运行时或需要创建 JSON 对象时,我不知道需要什么数据和/或类型。因此,我不能像下面这样简单地创建一个对象:
type Foo struct {
A string `json:"a"`
B int `json:"b"`
}
英文:
I want to create a map that I can transform into a json object such as
{
"a": "apple",
"b": 2
}
but golang specifies that the map be declare with types, so I can have map[string]string or map[string]int. How do I create a json object like the above?
Note: I won't know what data and/or types I need until runtime or when I need to create the json object. Therefore I can't just create an object like
type Foo struct {
A string `json:"a"`
B int `json:"b"`
}
答案1
得分: 69
你可以始终使用interface{}
来存储任何类型。正如encoding/json
包中的文档所说:
要将JSON解组为接口值,Unmarshal将JSON解组为接口值中包含的具体值。如果接口值为nil,即没有存储在其中的具体值,Unmarshal将在接口值中存储以下之一:
- bool,用于JSON布尔值
- float64,用于JSON数字
- string,用于JSON字符串
- []interface{},用于JSON数组
- map[string]interface{},用于JSON对象
- nil,用于JSON null
只需执行以下操作:
m := map[string]interface{}{"a":"apple", "b":2}
英文:
You can always use interface{}
to store any type. As the documentation in the encoding/json
package says:
>To unmarshal JSON into an interface value, Unmarshal unmarshals the JSON into the concrete value contained in the interface value. If the interface value is nil, that is, has no concrete value stored in it, Unmarshal stores one of these in the interface value:
>bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null
Just do the following:
m := map[string]interface{}{"a":"apple", "b":2}
答案2
得分: 8
为了回应这些评论,我认为更容易为Map和Slice添加类型定义,这样你就不必担心复杂的字面声明了:
package main
import "fmt"
type Map map[string]interface{}
type Slice []interface{}
func main() {
m := Map{
"a": "apple",
"b": 2,
"c": Slice{"foo", 2, "bar", false, Map{"baz": "bat", "moreFoo": 7}},
}
fmt.Println(m)
}
https://golang.org/ref/spec#Type_definitions
英文:
To respond to the comments, I think it is easier to add type definitions for Map and Slice, then you don't have to worry about complex literal declarations:
package main
import "fmt"
type Map map[string]interface{}
type Slice []interface{}
func main() {
m := Map{
"a": "apple",
"b": 2,
"c": Slice{"foo", 2, "bar", false, Map{"baz": "bat", "moreFoo": 7}},
}
fmt.Println(m)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论