【发布时间】:2017-12-18 16:31:10
【问题描述】:
我只是找不到获取指向给定结构的每个属性的指针切片的方法。我正在使用反射来获取我的指针(感谢https://stackoverflow.com/a/24348352/6093604)
if valueField.CanAddr() {
address = fmt.Sprintf("0x%X", valueField.Addr().Pointer())
}
如您所见, valueField.Addr().Pointer() 返回一个指针 addr 值,但是,使用反射,我想为 sql.Rows.Scan() 获取一个可用的指针
所以我做的是:
func StructAttributesToPointersSlice(object interface{}) []interface{} {
val := reflect.ValueOf(object)
if val.Kind() == reflect.Interface && !val.IsNil() {
elm := val.Elem()
if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
val = elm
}
}
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
var ptrs []interface{}
for i := 0; i < val.NumField(); i++ {
valueField := val.Field(i)
if valueField.Kind() == reflect.Ptr {
valueField = valueField.Elem()
}
if valueField.CanAddr() {
ptrs = append(ptrs, valueField.Addr().Pointer())
}
}
return ptrs
}
但是当我尝试将它用于Scan() sql 函数时:
var values []interface{}
// Iterate over each rows got from the query
for rows.Next() {
ptrs := utils.StructAttributesToPointersSlice(&newObject)
for _, item := range ptrs {
fmt.Println(reflect.TypeOf(item))
}
err = rows.Scan(ptrs...)
if err != nil {
return nil, model.Status{Code: http.StatusInternalServerError, Error: err.Error()}
} else {
values = append(values, newObject)
}
}
我收到此错误:
sql:列索引 0 上的扫描错误:目标不是指针
我知道这是因为它不是好类型,因为它是 uintptr,但是如何将其转换为可用指针?
谢谢
【问题讨论】:
-
Addr() 已经返回一个指针值。在其上调用 Pointer() 是错误的。可能您应该通过 Interface() 而不是 Pointer() 提取实际指针。