几乎是一个新手,我第一次提出一个问题,关于接口,类型和地图的问题。
所以,我的出发点是一个数据库查询,它检索像这样的对象:
+-------------+---------------------+----------+------------+
| category_id | category_name | group_id | group_name |
+-------------+---------------------+----------+------------+
| 1 | Category1 | 1 | Group1 |
| 1 | Category1 | 2 | Group2 |
| 1 | Category1 | 3 | Group3 |
| 1 | Category2 | 4 | Group4 |
| 2 | Category2 | 5 | Group5 |
+-------------+---------------------+----------+------------+
我的最终目标是拥有一个json对象,该类别属于该类别下的相同类别,如下所示:
{
"id": 1,
"name": "category1",
"groups": [
{
"id": 1,
"name": "Group1"
},
{
"id": 2,
"name": "Group2"
},
{
"id": 3,
"name": "Group3"
}
]
},
{
"id": 2,
"name": "Category2",
"groups": [
{
"id": 4,
"name": "Group4"
},
{
"id": 5,
"name": "Group5"
}
]
}
我不想使用多个查询,因为这只是最终查询的一部分,我只使用了2个字段来更清楚这个例子。在我目前的情况下,我只有5个级别......
所以我创建了一个应该在我的对象的所有级别上使用的结构,它实现了一个接口:
type NestedMapObjs interface {
getOrderedKeys() []int
}
以及实现此接口的类型,应该是map of int
,以便将元素附加到正确的映射:
type BuilderMapObjs map[int]NestedMapObj
NestedMapObject
时:
type NestedMapObj struct {
ID int
Name *string
NestedObj NestedMapObjs
}
所以,在我构建我想要的地图对象的方法上,我没有问题添加我的对象的第一级(Category
)但是,我在第二级发现了一些问题,第一组。特别是,这是我添加新行的函数:
func (m BuilderMapObjs) addNewRow(scanned audienceBuilderScannedObject) error {
if _, ok := m[scanned.CategoryID]; !ok {
var innerObjs BuilderMapObjs
innerObjs = make(BuilderMapObjs, 0)
m[scanned.CategoryID] = NestedMapObj{
ID: scanned.CategoryID,
Name: &scanned.CategoryName,
NestedObj: innerObjs,
}
}
if _, ok := m[scanned.CategoryID].NestedObj[scanned.GroupID]; !ok {
m[scanned.CategoryID].NestedObj[scanned.GroupID] = NestedMapObj{
ID: scanned.GroupID,
Name: &scanned.GroupName,
}
}
return nil
}
(我知道,我可以重构并使这段代码更具可读性,但现在这不是重点......)
问题是当我尝试通过其键获取内部对象时,以及当我尝试添加它时。这一行:
m[scanned.CategoryID].NestedObj[scanned.GroupID]
产生此错误:invalid operation: m[scanned.CategoryID].NestedObj[scanned.GroupID] (type NestedMapObjs does not support indexing)
实际上,我刚刚发现通过更好的实现,在界面中实现了另外两个方法(getIndex
和addToIndex
)我修复了问题,但我想了解这个问题。
为什么我在内部对象上有错误而在外部对象上没有错误?
感谢阅读,直到这一刻!