dongsilu2237 2018-04-03 23:13
浏览 298
已采纳

为什么不能在go中传递`func()[] int`作为`func()[] interface {}`?

I have the following definition:

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)

This is met with:

cannot use source (type func() []int) as type func() []interface {} in argument to c.RegisterSource
  • 写回答

2条回答 默认 最新

  • duanjianlu0506 2018-04-04 18:47
    关注

    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. A slice is a backing storage array plus several integers containing the size and capacity of the slice.

      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.

      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.

      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.

    2. 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).

    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.

    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.

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊
  • ¥15 安装svn网络有问题怎么办