指向地图范围或接口切片范围的循环变量的指针{}
Pointer to loop variable for range over map or slice of interface{}
我正在使用 go-hdf5,但在尝试从地图循环写入属性时遇到了问题。
属性创建正确(名称和数据类型正确)但写入的值是垃圾。
循环外的相同代码工作正常。我尝试了 v := v
习惯用法并将代码包装在闭包中以捕获 v
但它没有什么区别。
这是代码的要点(为清楚起见,特意省略了错误检查):
m := map[string]interface{"foo", 42}
for k, v := range m {
// [...]
v := v
attr.Write(&v, dtype)
}
Write
method 正在使用反射获取指向该值的指针并将其转发给 C 库。代码的相关部分只是:
func (s *Attribute) Write(data interface{}, dtype *Datatype) error {
v := reflect.ValueOf(data)
addr := unsafe.Pointer(v.Pointer())
return h5err(C.H5Awrite(s.id, dtype.id, addr))
}
如果我用一片 interface{}
替换地图,我会得到完全相同的问题,所以我的直觉是这与循环变量的绑定有关,但 v := v
没有帮不上忙所以我不确定。
我对 Go、HDF5(C 库)和 go-hdf5 非常熟悉,但我真的被困在这里。有什么想法吗?
顺便说一句,我正在使用 go1.5.1 darwin/amd64。
Write
方法需要一个指向值的指针,而不是指向包含该值的接口的指针。你可以使用反射得到它:
u := reflect.New(reflect.ValueOf(v).Type())
u.Elem().Set(reflect.ValueOf(v))
v := u.Interface()
我正在使用 go-hdf5,但在尝试从地图循环写入属性时遇到了问题。
属性创建正确(名称和数据类型正确)但写入的值是垃圾。
循环外的相同代码工作正常。我尝试了 v := v
习惯用法并将代码包装在闭包中以捕获 v
但它没有什么区别。
这是代码的要点(为清楚起见,特意省略了错误检查):
m := map[string]interface{"foo", 42}
for k, v := range m {
// [...]
v := v
attr.Write(&v, dtype)
}
Write
method 正在使用反射获取指向该值的指针并将其转发给 C 库。代码的相关部分只是:
func (s *Attribute) Write(data interface{}, dtype *Datatype) error {
v := reflect.ValueOf(data)
addr := unsafe.Pointer(v.Pointer())
return h5err(C.H5Awrite(s.id, dtype.id, addr))
}
如果我用一片 interface{}
替换地图,我会得到完全相同的问题,所以我的直觉是这与循环变量的绑定有关,但 v := v
没有帮不上忙所以我不确定。
我对 Go、HDF5(C 库)和 go-hdf5 非常熟悉,但我真的被困在这里。有什么想法吗?
顺便说一句,我正在使用 go1.5.1 darwin/amd64。
Write
方法需要一个指向值的指针,而不是指向包含该值的接口的指针。你可以使用反射得到它:
u := reflect.New(reflect.ValueOf(v).Type())
u.Elem().Set(reflect.ValueOf(v))
v := u.Interface()