英文:
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
方法使用反射来获取值的指针,并将其传递给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。
英文:
I'm using go-hdf5 and I'm hitting a problem when trying to write attributes in a loop from a map.
The attributes are created correctly (correct name and datatype) but the written value is garbage.
The same code outside of the loop works fine. I tried both the v := v
idiom and wrapping the code in a closure to capture v
but it doesn't make a difference.
Here is the gist of the code (error checking intentionally left out for clarity):
m := map[string]interface{"foo", 42}
for k, v := range m {
// [...]
v := v
attr.Write(&v, dtype)
}
The Write
method is using reflection to grab a pointer to the value and forwards it to the C library. The relevant part of the code is just:
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))
}
If I replace the map by a slice of interface{}
, I get the exact same problem so my hunch is that this has to do with the binding of loop variables, but yet v := v
doesn't help so I'm not sure.
I'm quite familiar with Go, HDF5 (C library) and go-hdf5 but I'm really stuck here. Any idea?
BTW I'm using go1.5.1 darwin/amd64.
答案1
得分: 0
Write
方法需要一个指向值的指针,而不是一个指向包含该值的接口的指针。你可以使用反射来获取它:
u := reflect.New(reflect.ValueOf(v).Type())
u.Elem().Set(reflect.ValueOf(v))
v := u.Interface()
英文:
The Write
method needs a pointer to a value, not a pointer to an interface containing the value. You can get it using reflection:
u := reflect.New(reflect.ValueOf(v).Type())
u.Elem().Set(reflect.ValueOf(v))
v := u.Interface()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论