英文:
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 : <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
答案1
得分: 2
我不是Go的作者或者其他什么,但我认为Go的设计是由三个特性决定的:
第一个特性导致了像Int
、Float
、Bool
、String
等方法的存在。除了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.
答案2
得分: 2
Go 1.5(2015年8月)应该允许您打印Reflect.Value()
参数的实际值。
请参阅review 8731和commit 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论