【问题标题】:Error making a []map[string]interface{} with for loop -> panic: assignment to entry in nil map使用 for 循环创建 []map[string]interface{} 时出错 -> 恐慌:分配给 nil 映射中的条目
【发布时间】:2020-09-28 07:52:26
【问题描述】:

我正在尝试使用这样的循环构建 []map[string]interface{}:

package main

import (
    "encoding/json"
    "fmt"
)

type People []struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func main() {
    resp := `[{"name":"Test","age":15}, {"name":"Test2","age":25}]`
    data := &People{}
    _ = json.Unmarshal([]byte(resp), data)
    m := make([]map[string]interface{}, len(*data))
    for k, v := range *data {
        m[k]["Name"] = v.Name
        m[k]["Age"] = v.Age
    }
    fmt.Println(m)
    fmt.Printf("%T", m)
}

但我总是收到这个错误:

恐慌:分配给 nil 映射中的条目

goroutine 1 [运行]: main.main() /tmp/sandbox300360207/prog.go:19 +0x17a

我不能使用 m := make(People, len(*data))m[k].Name = v.Name,因为我需要类型为 []map[string]interface{} 而不是 main.People

我也试过这个:

func main() {
    resp := `[{"name":"Test","age":15}, {"name":"Test2","age":25}]`
    data := &People{}
    _ = json.Unmarshal([]byte(resp), data)
    m := make([]map[string]interface{}, len(*data))
    for k, v := range *data {
        m[k] = map[string]interface{"Name": v.Name, "Age": v.Age}
    }
    fmt.Println(m)
    fmt.Printf("%T", m)
}

但是得到了这个错误:

./prog.go:19:31:语法错误:意外的文字“名称”,期待 方法或接口名称

【问题讨论】:

    标签: arrays dictionary for-loop go slice


    【解决方案1】:

    您的make() 只创建了一个地图切片,但它的元素都是nils。您不能将对“插入”到 nil 映射中,您还必须在循环内创建映射:

    m := make([]map[string]interface{}, len(*data))
    for k, v := range *data {
        m[k] = make(map[string]interface{})
        m[k]["Name"] = v.Name
        m[k]["Age"] = v.Age
    }
    

    输出将是(在Go Playground 上尝试):

    [map[Age:15 Name:Test] map[Age:25 Name:Test2]]
    []map[string]interface {}
    

    您也可以使用复合文字来创建地图:

    m[k] = map[string]interface{}{}
    

    您的第二次尝试失败了,因为语法无效。类型是map[string]interface{},因此要创建这种类型的值的复合文字必须有一个额外的大括号对:map[string]interface{}{}。使用单个复合文字,这就是它的样子:

    for k, v := range *data {
        m[k] = map[string]interface{}{
            "Name": v.Name,
            "Age":  v.Age,
        }
    }
    

    输出是一样的。在Go Playground 上试试这个。

    【讨论】:

    • 很有意义,现在可以使用了,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多