【问题标题】:Implement Scan interface to read json array into map实现Scan接口将json数组读入map
【发布时间】:2017-11-03 12:29:12
【问题描述】:

我正在从 PostgreSQL 获取一个 JSON 数组,我想将它读入地图。我可以将这些值解组为 []string 切片,但我真正想要的是 map[string]bool

我使用 Scan 接口为列编写了一个自定义类型,该接口首先将 JSON 数组转换为字符串切片,然后将每个字符串作为键读取到自定义映射类型中。

type custMap map[string]bool

func (m *custMap) Scan(src interface{}) error {
  b, ok := src.([]byte)
  if !ok {
    return error(errors.New("Error Scanning Array"))
  }

  s := make([]string, 0)
  json.Unmarshal(b, &s)
  for _, v := range s {
    (*m)[v] = true
  }

  return nil
}


type data struct {
  vals custMap `json: "vals"`
}

我试图扫描的查询返回一行,其中有一列 vals,它是一个 JSON 数组:["some", "arr", "vals"],其中使用自定义类型,如下所示:

var d models.data
sqlDB.QueryRow().Scan(&d.vals)

我的预期输出是具有以下形状的结构

{ vals: map[string]bool { "some": true, "arr": true, "vals": true }

这编译得很好,但是我的代码因为“分配给 nil 映射中的条目”而出现恐慌

如何修复我的扫描功能?甚至可以用地图类型来做到这一点吗?

【问题讨论】:

  • 请提供源行号和错误信息。我怀疑错误发生在(*m)[v] = true 线上,但这只是我的怀疑。
  • 是的!这就是我得到'分配到零地图中的条目'
  • 抛出的具体错误是 0http: panic serving [::1]:59847: assignment to entry in nil map。我知道是那一行,因为在我第一次尝试时我没有在那里使用指针:m[v] = true 这导致了这个编译错误:无效操作:m[v](类型 *SCMap 不支持索引)

标签: arrays json go


【解决方案1】:

The Go Programming Language Specification

Map types

地图是一种类型的无序元素组,称为 元素类型,由一组另一种类型的唯一键索引,称为 密钥类型。未初始化的map的值为nil。

使用内置函数 make 生成一个新的空映射值,该函数 将地图类型和可选容量提示作为参数:

make(map[string]int)
make(map[string]int, 100)

初始容量不限制其大小:地图会增长以适应 存储在其中的项目数,nil 地图除外。一种 nil map 等价于一个空 map,除了没有元素可以是 已添加。

我没有看到 make 来初始化您的地图:“nil 地图相当于一个空地图,但不能添加任何元素。”

【讨论】:

    【解决方案2】:

    您在未初始化的地图上调用*custMap 类型的方法Scan。初始化d.vals或者喜欢

    d.vals = custMap{}
    

    d.vals = make(custMap)
    

    其他答案已经提供了解释。

    【讨论】:

      猜你喜欢
      • 2021-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-21
      • 1970-01-01
      • 1970-01-01
      • 2019-04-09
      相关资源
      最近更新 更多