英文:
How to print type of array items in Go?
问题
当我尝试对一些代码进行单元测试时,我有一些像这样的断言:
expected := []interface{}{1}
actual := []interface{}{float64(1)}
if !reflect.DeepEqual(expected, actual); {
t.Errorf("期望值 <%T> %#v 与实际值 <%T> %#v 不相等", actual, actual, expected, expected);
}
并且得到了以下输出:
期望值 <[]interface {}> []interface {}{1} 与实际值 <[]interface {}> []interface {}{1}
我该如何打印这个消息以使其更明确?
谢谢!
英文:
When I try to unit test some code, I have some assertion like this:
expected := []interface{}{1}
actual := []interface{}{float64(1)}
if !reflect.DeepEqual(expected, actual); {
t.Errorf("Expected <%T> %#v to equal <%T> %#v", actual, actual, expected, expected);
}
And got this output:
Expected <[]interface {}> []interface {}{1} to equal <[]interface {}> []interface {}{1}
How can I print this message to be more explicit?
Thanks!
<iframe src="http://play.golang.org/p/JigknXTcdx" frameborder="0" style="width: 100%; height: 100%"><a href="http://play.golang.org/p/JigknXTcdx">see this code in play.golang.org</a></iframe>
答案1
得分: 3
你正在打印切片的类型,而不是元素的类型。切片的类型是[]interface{}
,这就是你看到的结果。
如果你想要看到元素的动态类型(它们的静态类型始终是interface{}
),那么可以打印元素的类型:
fmt.Printf("Expected element type: %T, got: %T", expected[0], actual[0])
这将输出:
Expected element type: int, got: float64
注意:
上面的代码假设你正在比较包含1个元素的两个切片。如果你不想检查切片的长度,并且想处理任意长度的切片,你可以使用其他的格式化动词。例如,你可以使用%t
动词,它期望一个bool
值,并打印true
或false
。请注意,这只是一种实现决策,并不是保证,但是使用%t
将打印所有切片元素;如果元素的类型是bool
,则打印相应的bool
值;如果元素的类型不是bool
,则打印元素的动态类型和值。
示例:
data := []interface{}{1, float64(2), "3", time.Now()}
fmt.Printf("%t", data)
输出:
[%!t(int=1) %!t(float64=2) %!t(string=3) {%!t(int64=63393490800) %!t(int32=0) %!t(*time.Location=&{ [] [] 0 0 <nil>})}]
这看起来有点丑,但包含了许多有用的信息(例如类型、值)。
英文:
You are printing the types of the slices, not the types of the elements. And types of the slices are []interface{}
. That's why you see that.
If you want to see the dynamic types of the elements (their static type is always interface{}
), then print the types of the elements:
fmt.Printf("Expected element type: %T, got: %T", expected[0], actual[0])
Which will output:
Expected element type: int, got: float64
Note:
The above code assumes you are comparing 2 slices with 1 element. If you don't want to check slice length and you want to handle slices with any length, you can use other verbs. For example you can use the %t
verb which expects a bool
value and wants to print true
or false
. Note that this is just an implementation decision and not guaranteed, but using %t
for example will print all the slice elements; printing the respective bool
value if it is of type bool
, and will print the dynamic type and value of the element if the it is not of type bool
.
Example:
data := []interface{}{1, float64(2), "3", time.Now()}
fmt.Printf("%t", data)
Output:
[%!t(int=1) %!t(float64=2) %!t(string=3)
{%!t(int64=63393490800) %!t(int32=0) %!t(*time.Location=&{ [] [] 0 0 <nil>})}]
It's a bit ugly, but contains many useful info (e.g. types, values).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论