通过interface{}设置指针的值无法生效。

huangapple go评论88阅读模式
英文:

setting a value of a pointer does not work through interface{}

问题

以下是稍作修改的示例,来自于Go语言的反射规则(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() {

  // 这一部分按预期工作,当完成时,x.x将为7.1
  var x = T{3.4}
  p := reflect.ValueOf(&x.x) // 注意:取x的地址。
  v := p.Elem()
  v.SetFloat(7.1)
  fmt.Println(x.x, x) // 7.1 {7.1}

  // 这一部分我不明白为什么x.x没有被设置为7.1
  x = T{3.4}
  rowmap := x.RowMap()
  p = reflect.ValueOf(rowmap["x"]) // rowmap["x"] => &x.x,与上面类似,但包含在interface{}中
  v = p.Elem()
  v.SetFloat(7.1)
  fmt.Println(x.x, x) // 3.4 {3.4}  ?? 嗯,应该是 // 7.1 {7.1}

}

希望对你有帮助!

英文:

Below is slightly modified example from the go laws of reflection http://blog.golang.org/laws-of-reflection. The 2nd code section uses a pointer from a map[string]interface{} and it does not work, what am I doing wrong?

Thanks

//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}

}

答案1

得分: 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的地址,看看它们是如何不同的。

英文:

>Elem returns the value that the interface v contains or that the pointer v points to.

Try printing the following and you'll see what you want to see but x does not change meaning it's never being updated.

fmt.Println(v.Float()) // 7.1

You need to pass a pointer to your method. Change your method signature to look like this

func (x *T) RowMap() map[string]interface{} {

Pass a pointer instead of a copy.

I've added some print statements that I think will help clear things up http://play.golang.org/p/xcFMicIPcP

Look at the address of x inside and outside of your method and see how they're different.

huangapple
  • 本文由 发表于 2014年3月3日 14:21:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/22139989.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定