将字符串映射到json对象的多个类型?

Der*_*rek 21 json go

我想创建一个可以转换为json对象的地图,例如

{
   "a": "apple",
   "b": 2
}
Run Code Online (Sandbox Code Playgroud)

但是golang指定地图是用类型声明的,所以我可以有map [string] string或map [string] int.如何像上面那样创建一个json对象?

注意:在运行时或需要创建json对象时,我不知道需要什么数据和/或类型.因此,我不能只创建一个像这样的对象

type Foo struct {
    A string `json:"a"`
    B int `json:"b"`
}
Run Code Online (Sandbox Code Playgroud)

ANi*_*sus 39

您始终可以interface{}用来存储任何类型.正如encoding/json包中的文档所说:

为了将JSON解组为接口值,Unmarshal将JSON解组为接口值中包含的具体值.如果接口值为nil,即没有存储具体值,则Unmarshal将其中一个存储在接口值中:

bool,用于JSON布尔值
float64,用于JSON数字
字符串,用于JSON字符串
[] interface {},用于JSON数组
map [string] interface {},用于JSON对象
nil用于JSON null

只需执行以下操作:

m := map[string]interface{}{"a":"apple", "b":2}
Run Code Online (Sandbox Code Playgroud)

  • @BrantleyBeaird 当然!空接口(`interface{}`)包含任何类型,包括数组。由于您的数组本身包含任意类型,因此它将变成类型“[]interface{}” (2认同)
  • 接口类型(其中`interface {}`是一个指定无方法的接口类型)可以保存任何底层类型,但是因此它们在内存使用方面增加了运行时开销(在将值转换为接口时存储其他类型信息)价值)和一些处理.合理的价格要支付动态语言可能习惯的一些灵活性,但在没有理由的情况下不能使用.除另一种接口类型外,接口类型可以包含任何基础类型 这包括普通类型,如int,float64,还包括数组,映射,通道等. (2认同)
  • @ErtuğrulAltınboğa 我有点不清楚。对于复合文字(结构体、数组、切片和映射),您必须首先指定类型。它将是: `m := map[string]interface{}{"a": "apple", "b": 2, "c": []interface{}{"foo", 2, "bar", false, map[string]接口{}{"baz": "bat", "moreFoo": 7}}}` (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)
}
Run Code Online (Sandbox Code Playgroud)

https://golang.org/ref/spec#Type_definitions