Golang赋值[] map [string] struct error

时间:2014-06-14 15:47:56

标签: data-structures struct go maps variable-assignment

正如您可能从以下代码中可以看出,我正在开发一个项目,该项目根据mongoDB中的数据创建csv报告。在获得我需要的数据之后,我需要将数据结构化为更合理的数据,然后它在数据库中是如何存在的,这是相当可怕的(不是我的行为),几乎不可能以我需要的方式打印。对我来说最有意义的结构是数据名称映射的片(对于每个数据文档)到保存该名称数据的结构。然后我只需循环遍历文档并将值填充到它们所属的结构中。

我的实现是

type mongo_essential_data_t struct {
        caution string
        citation string
        caution_note string
}

mongo_rows_struct := make([]map[string]mongo_essential_data_t, len(mongodata_rows))

//setting the values goes like this
mongo_rows_struct[i][data_name].caution_note = fmt.Sprint(k)
//"i" being the document, "k" being the data I want to store

然而,这不起作用。在“开始运行”时,它返回./answerstest.go:140: cannot assign to mongo_rows_struct[i][data_name].caution_note。我是Go的新手,不知道为什么我不允许这样做。我确定这是一种无效的方式来引用特定的数据位置,如果甚至可以在Go中引用它。完成此设置线的另一种方法是什么?如果以我想要的方式完成这项工作太多,我愿意使用不同类型的数据结构,并愿意接受建议。

2 个答案:

答案 0 :(得分:6)

这是Golang的一个已知问题,称为issue 3117。您可以使用临时变量来解决它:

var tmp = mongo_rows_struct[i][data_name]
tmp.caution_note = fmt.Sprint(k)
mongo_rows_struct[i][data_name] = tmp 

答案 1 :(得分:0)

根据我的理解,当你写:
    mongo_rows_struct[i][data_name]
编译器将生成代码,该代码将返回mongo_essential_data_t结构的副本(因为结构中的go是值类型,而不是引用类型),以及
    mongo_rows_struct[i][data_name].caution_note = fmt.Sprint(k)
将为该副本写入新值。之后,副本将被丢弃。显然,它不是你所期望的。所以Go编译器生成错误以防止这种误解 为了解决这个问题,你可以:
1.将数据类型的定义更改为     []map[string]*mongo_essential_data_t
2.明确创建结构的副本,在该副本中进行更改并将其写回地图
    data := mongo_rows_struct[i][data_name]
    data.caution_note = fmt.Sprint(k)
    mongo_rows_struct[i][data_name] = data

当然,首选解决方案更可取,因为您可以避免不必要的数据复制