1 回答
TA贡献1836条经验 获得超3个赞
该错误表明您想要获取其地址的值是不可寻址的。这是因为即使您将指针传递给GetSqlColumnToFieldMap(),您也会立即取消引用它并稍后使用非指针值。
这个值被包装在一个interface{}when passed to中reflect.ValueOf(),并且包装在接口中的值是不可寻址的。
您不能取消引用指针,而是使用Type.Elem()andValue.Elem()获取元素类型和指向的值。
是这样的:
func GetSqlColumnToFieldMap(model *ExampleStruct) map[string]interface{} {
t := reflect.TypeOf(model).Elem()
v := reflect.ValueOf(model).Elem()
columnToDataPointerMap := make(map[string]interface{})
for i := 0; i < v.NumField(); i++ {
sql_column := t.Field(i).Tag.Get("sql")
structValue := v.Field(i)
columnToDataPointerMap[sql_column] = structValue.Addr()
}
return columnToDataPointerMap
}
通过这个简单的更改,它就起作用了!而且它不依赖于参数类型,您可以将其更改为interface{}并传递任何结构指针。
func GetSqlColumnToFieldMap(model interface{}) map[string]interface{} {
// ...
}
测试它:
type ExampleStruct struct {
ID int64 `sql:"id"`
AID string `sql:"a_id"`
UserID int64 `sql:"user_id"`
}
type Point struct {
X int `sql:"x"`
Y int `sql:"y"`
}
func main() {
fmt.Println(GetSqlColumnToFieldMap(&ExampleStruct{}))
fmt.Println(GetSqlColumnToFieldMap(&Point{}))
}
输出(在Go Playground上尝试):
map[a_id:<*string Value> id:<*int64 Value> user_id:<*int64 Value>]
map[x:<*int Value> y:<*int Value>]
请注意,Value.Addr()返回包含在reflect.Value. 要“展开”指针,请使用Value.Interface():
func GetSqlColumnToFieldMap(model interface{}) map[string]interface{} {
t := reflect.TypeOf(model).Elem()
v := reflect.ValueOf(model).Elem()
m := make(map[string]interface{})
for i := 0; i < v.NumField(); i++ {
colName := t.Field(i).Tag.Get("sql")
field := v.Field(i)
m[colName] = field.Addr().Interface()
}
return m
}
这将输出(在Go Playground上尝试):
map[a_id:0xc00007e008 id:0xc00007e000 user_id:0xc00007e018]
map[x:0xc000018060 y:0xc000018068]
- 1 回答
- 0 关注
- 61 浏览
添加回答
举报