为什么在golang中,使用Println无法打印出int的真实值,而reflect.ValueOf却可以?

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

Why reflect.ValueOf can not print out true value of int using Println in golang

问题

func main() {
var val interface{} = 11
fmt.Println(reflect.ValueOf(val))
}//打印结果:<int Value>

但是当我将字符串,比如"Hello",传递给val时,它会打印出字符串本身。
我注意到value结构体有一个方法

func (v Value) String() string

它说如果v的类型不是字符串,它会返回一个形如"[T value]"的字符串,其中T是v的类型,但是为什么不返回类似于[int 11]的东西呢?我也知道我应该在ValueOf()后面添加一个Int()函数来获取val的实际值,但是我不理解value结构体、String函数和Println函数之间的内部关系。

英文:
func main() {
	var val interface{} = 11
	fmt.Println(reflect.ValueOf(val))	
}//print out : &lt;int Value&gt;

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

答案1

得分: 2

我不是Go的作者或者其他什么,但我认为Go的设计是由三个特性决定的:

  • Getter方法通常省略Get前缀 来源
  • 如果有的话,fmt包会使用String方法 来源
  • 接口的满足是隐式的

第一个特性导致了像IntFloatBoolString等方法的存在。除了String方法外,所有这些方法在调用错误类型的值时都会引发panic。这是因为String方法会被fmt包和许多其他包用来获取值的字符串表示,而仅仅将字符串值作为可打印的是不合理的。可以说,应该有另一个方法返回底层的字符串而不是String,但这会导致API的一致性较差,所以他们选择了较小的邪恶。

反射文档

英文:

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

答案2

得分: 2

Go 1.5(2015年8月)应该允许您打印Reflect.Value()参数的实际值。
请参阅review 8731commit 049b89d,作者是Rob Pike (robpike)

> ## fmt: 将reflect.Value视为其所持有的值

> 当将reflect.Value传递给Printf(等等)时,fmt调用了String方法,该方法不会透露其内容。
要获取内容,可以调用Value.Interface(),但如果Value未导出或受到其他限制,则此操作是非法的。

> 这个更改通过对fmt包进行微小的更改来改善情况:当我们将reflect.Value作为参数时,我们将其视为在包内部创建的reflect.Value一样对待。
这意味着我们始终打印Value的内容,就好像它是Printf的参数一样。

> 这可能是一个破坏性的更改,但我认为这是一个真正的改进,而且与我们对该包中格式化输出所做的许多其他微调一样,并没有更大的破坏。

英文:

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.

huangapple
  • 本文由 发表于 2014年4月9日 22:58:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/22966494.html
匿名

发表评论

匿名网友

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

确定