以下是来自反思法律http://blog.golang.org/laws-of-reflection的略微修改的示例。第二个代码部分使用来自map [string] interface {}的指针,它不起作用,我做错了什么?
由于
//http://play.golang.org/p/LuMBUWLVT6
package main
import (
"fmt"
"reflect"
)
type T struct {
x float64
}
func (x T) RowMap() map[string]interface{} {
return map[string]interface{}{
"x": &x.x,
}
}
func main() {
// this section works as expected, x.x will be 7.1 when done
var x = T{3.4}
p := reflect.ValueOf(&x.x) // Note: take the address of x.
v := p.Elem()
v.SetFloat(7.1)
fmt.Println(x.x, x) // 7.1 {7.1}
// this section I do not understand why x.x is not being set to 7.1
x = T{3.4}
rowmap := x.RowMap()
p = reflect.ValueOf(rowmap["x"]) // rowmap["x"] => &x.x just like above, but is containted in interface{}
v = p.Elem()
v.SetFloat(7.1)
fmt.Println(x.x, x) // 3.4 {3.4} ?? huh, should be // 7.1 {7.1}
}
答案 0 :(得分:2)
Elem返回接口v包含的值或指针v指向的值。
尝试打印以下内容,您会看到您想要看到的内容,但x不会改变,这意味着它永远不会被更新。
fmt.Println(v.Float()) // 7.1
您需要将指针传递给您的方法。将方法签名更改为如下所示
func (x *T) RowMap() map[string]interface{} {
传递指针而不是副本。
我添加了一些打印声明,我认为这些声明有助于清除http://play.golang.org/p/xcFMicIPcP
查看方法内外x
的地址,看看它们有何不同。