为什么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.
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
: treatreflect.Value
specially - as the value it holdsWhen a
reflect.Value
is passed toPrintf
(etc.),fmt
called theString
method, which does not disclose its contents.
To get the contents, one could callValue.Interface()
, but that is illegal if theValue
is not exported or otherwise forbidden.This CL improves the situation with a trivial change to the
fmt
package: when we see areflect.Value
as an argument, we treat it exactly as we treat areflect.Value
we make inside the package.
This means that we always print the contents of theValue
as if that was the argument toPrintf
.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.