为什么reflect.ValueOf不能在golang中使用Println打印出int的真实值

为什么reflect.ValueOf不能在golang中使用Println打印出int的真实值

问题描述:

func main() {
    var val interface{} = 11
    fmt.Println(reflect.ValueOf(val))   
}//print out : <int Value>

But after I pass string,like "Hello" to val,it will print out the string itself. I notice that value struct has a method

func (v Value) String() string

It says that if v'type is not a string,it returns a string of the form "[T value]" where T is v's type,but,why not returning something like [int 11],I also know that I should append an Int() function to ValueOf() to get the actual value of val,but I do not understand the internal relationship between value struct,and String function and the Println function

I'm not a Go author or anything, but I think the design is a product of three properties of Go:

  • Getters commonly leave off Get source
  • The fmt package uses a String method if it is available. source
  • Interfaces are satisfied implicitly

The first leads to the methods like Int, Float, Bool, String etc. All of these methods will panic if called on a value of the wrong type, except String. This is because String would be used by fmt, and likely many other packages to get a string representation of the value, and it is surely unreasonable for only string values to be printable. Arguably there should be another method which returns the underlying string instead of String, but that would mean less consistency in the api, so they chose the lesser of two evils.

Reflect Documentation

Go 1.5 (August 2015) should allow you to print the actual value of a Reflect.Value() argument.
See review 8731 and commit 049b89d by Rob Pike (robpike):

fmt: treat reflect.Value specially - as the value it holds

When a reflect.Value is passed to Printf (etc.), fmt called the String method, which does not disclose its contents.
To get the contents, one could call Value.Interface(), but that is illegal if the Value is not exported or otherwise forbidden.

This CL improves the situation with a trivial change to the fmt package: when we see a reflect.Value as an argument, we treat it exactly as we treat a reflect.Value we make inside the package.
This means that we always print the contents of the Value as if that was the argument to Printf.

This is arguably a breaking change but I think it is a genuine improvement and no greater a break than many other tweaks we have made to formatted output from this package.