为什么我不能在go中传递`func()[] int`作为`func()[] interface {}`? [英] Why can't I pass a `func() []int` as `func() []interface{}` in go?
问题描述
我有以下定义:
func (c *Collector) RegisterSource(f func() []interface{}) {
c.source = f
}
我尝试按以下方式调用它,但收到错误消息:
I attempt to call it as follows but get an error:
func source() []int {
return []int{ 0, 1, 2, 3, 4 }
}
...
c.RegisterSource(source)
这符合:
cannot use source (type func() []int) as type func() []interface {} in argument to c.RegisterSource
推荐答案
相关的Go FAQ条目指出[]T
和[]interface{}
«在内存中没有相同的表示形式".
The relevant Go FAQ entry states that []T
and []interface{}
«do not have the same representation in memory».
要了解原因,我们来剖析两件事:
To understand why, let's dissect two things:
-
切片是后备存储数组加包含大小和容量的几个整数 切片.
A slice is a backing storage array plus several integers containing the size and capacity of the slice.
在Go中,数组并不是某种意义上的高级";相反, 它们所包含的元素的布局是严格定义的:它们都是 包含在彼此相邻的连续内存区域中.
In Go, arrays are not somehow "high-level"; on the contrary, the layout of the elements they contain is strictly defined: they are all contained in a contiguous region of memory, adjacent to each other.
这意味着,在切片[]T
的支持数组中,元素是
类型T
,它们每个都占用一个自然大小的内存区域
对于该类型T
,所有这些区域都彼此相邻
在单个连续的内存块中.
This means, that in the backing array of a slice []T
, elements are of
type T
, and each of them occupies a region of memory of a size natural
for that type T
, and all these regions are all adjacent to each other
in a single contiguous memory block.
这意味着切片[]int
的每个元素正好占据64位
(在8位字节上)在64位平台上-单个int
值的内存量
占据.
That means, each element of a slice []int
occupies exactly 64 bits
(8 bytes) on a 64-bit platform — the amount of memory a single int
value
occupies.
任何接口类型的值,包括空接口,
interface{}
表示为包含两个指针的结构,
像这样:
A value of any interface type, including the empty interface,
interface{}
, is represented as a structure containing two pointers,
something like:
type iface struct {
realType *typeInfo
realValue *dataType
}
(有关如何表示接口的更多信息-此处).
(More on how interfaces are represented — here).
以上所有均值表示在切片[]interface{}
中每个元素占用
内存区域中两个指针的大小,并且这两个指针包含
内存中其他变量的地址-与单纯的整数值相反
包含在[]int
的元素中.
All of the above means in a slice []interface{}
each element occupies the
region of memory the size of two pointers, and these two pointers contain
addresses of other variables in memory — as opposed to mere integer values
contained by elements of []int
.
这又意味着您不能只是投射" []int
到" []interface{}
—仅仅是因为存储在[]int
(int
)的任何元素中的值是
其结构(内存布局)与元素不兼容
[]interface{}
的值(一个包含两个指针的结构).
要从另一个产生一个,您需要分配一个slice并转换每个
源切片的元素与目标切片的匹配元素.
And this, in turn, means you can't just "cast" []int
"to" []interface{}
— simply because a value stored in any element of []int
(an int
) is
incompatible in its structure (memory layout) with an element
of []interface{}
(a struct containing two pointers).
To produce one from another, you need to allocate a slice and convert each
element of the source slice to a matching element of the destination one.
最后,这意味着如果函数返回类型为[]int
的切片,
该分片不能由期望分片的代码直接处理
键入[]interface{}
(反之亦然),这解释了为什么
您问题中的两个函数签名表示不兼容
类型.
Finally, this means if a function returns a slice of type []int
,
that slice cannot be directly processed by code expecting slices of
type []interface{}
(and vice-versa), and this explains why
the two function signatures from your question represent incompatible
types.
这篇关于为什么我不能在go中传递`func()[] int`作为`func()[] interface {}`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!