Golang 的 []interface{} 类型

Golang 的 []interface{} 类型

思考两个问题:

  1. func Foo(target []interface{}) 函数可以传入 []int 类型的 slice 吗?
  2. func Bar(fn func() interface{}) 函数可以传入 func() int 类型的函数吗?

我们都知道,如果单单使用 interface 类型作为参数类型,那么可以传入任何值。例如:

func Foo(a interface{}) {}

Foo(1)
Foo("str")
Foo(1.552)
Foo(nil)
Foo(func() (*Bar, error) {
    return nil, nil
})

但是当我们声明 interface{} slice 或是数组的时候,事情就变的不一样了:

func Foo(a []interface{}) {}

Foo([]int{1, 2, 3}) // 报错
Foo([]string{"1", "2", "3"}) // 报错

按照本身的设想,这里应该不管什么样的数组都可以作为参数传入,可是结果却恰恰相反:我们只能传入类型为 []interface{} 的元素。

为什么呢?

因为 []interface{} 类型变量拥有特定的内存结构

每个 interface{} 占两个字(32 位机器一个字是 32 位,64 位机器一个字是 64 位)。其中,一个字用于存放 interface{} 真正传入的数据的类型;另一个字用于指向实际的数据。

因此我们可以得出:长度为 n 的 []interface{} 切片的背后,是一个 n * 2 字 长的一块数据。这与一般的 []Type 类型切片不同的。

而长度为 n 的 []Type 切片的背后数据分配的大小为为 n * sizeof(Type) 字 长。

自然就不可以将 []int 类型作为 []interface{} 类型进行传递,只能自己写个循环将每一个 Type 都转化为 interface{}

同理,我们可以得到结论:func() interface{} 类型,只能匹配 interface{} 的返回值,不能使用 func() int 或是 func() string

(完)

posted @ 2022-01-15 18:58  徐航宇  阅读(1819)  评论(0编辑  收藏  举报