为什么我不能在go中传递`func()[] int`作为`func()[] interface {}`? [英] Why can't I pass a `func() []int` as `func() []interface{}` in go?

查看:137
本文介绍了为什么我不能在go中传递`func()[] int`作为`func()[] interface {}`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下定义:

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:

  1. 切片是后备存储数组加包含大小和容量的几个整数 切片.

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆