为什么可以';我不能在go中将'func()[]int'作为'func()[]接口{}'传递吗?

为什么可以';我不能在go中将'func()[]int'作为'func()[]接口{}'传递吗?,go,interface,Go,Interface,我有以下定义: func (c *Collector) RegisterSource(f func() []interface{}) { c.source = f } 我尝试按如下方式调用它,但得到一个错误: func source() []int { return []int{ 0, 1, 2, 3, 4 } } ... c.RegisterSource(source) 这方面的工作包括: cannot use source (type func() []int) as t

我有以下定义:

func (c *Collector) RegisterSource(f func() []interface{}) {
    c.source = f
}
我尝试按如下方式调用它,但得到一个错误:

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

因为[]int和[]interface是两种不同类型的切片,go不允许在这两种切片之间进行自动转换

你所能做的就是改变这个

func source() []int {
    return []int{ 0, 1, 2, 3, 4 }
}
到那

func source() []interface{} {
    return []interface{}{ 0, 1, 2, 3, 4 }
}

为了适合您为
RegisterSource
定义的函数签名

因为[]int和[]interface是两种不同类型的切片,而go不允许在这两种切片之间进行自动转换

你所能做的就是改变这个

func source() []int {
    return []int{ 0, 1, 2, 3, 4 }
}
到那

func source() []interface{} {
    return []interface{}{ 0, 1, 2, 3, 4 }
}
为了适合您为
RegisterSource
定义的函数签名

表示
[]T
[]interface{}
«在内存中没有相同的表示形式的状态

为了理解原因,让我们分析两件事:

  • 片是一个后备存储器加上几个包含大小和容量的整数 那一片

    在Go中,数组并不是某种程度上的“高级”;相反地, 它们包含的元素的布局是严格定义的:它们都是 包含在一个相邻的内存区域中,彼此相邻

    这意味着,在片
    []T
    的后备数组中,元素是 键入
    T
    ,它们各自占据一个自然大小的内存区域 对于该类型
    T
    ,所有这些区域都彼此相邻 在单个连续内存块中

    这意味着,片
    []int
    的每个元素正好占用64位 (8字节)在64位平台上-单个
    int
    值的内存量 占据

  • 任何接口类型的值,包括空接口,
    接口{}
    表示为包含两个指针的结构, 比如:

    type iface struct {
        realType  *typeInfo
        realValue *dataType
    }
    
    (更多关于如何表示接口的信息-)

  • 上述所有方法都意味着在片
    []接口{}
    中,每个元素占用 内存区域两个指针的大小,这两个指针包含 内存中其他变量的地址-而不仅仅是整数值 包含在
    []int
    的元素中

    这反过来意味着你不能将
    []int
    “强制转换”到“
    []interface{}
    ”——仅仅因为
    []int
    (一个
    int
    )的任何元素中存储的值都是 其结构(内存布局)与元素不兼容 属于
    []接口{}
    (包含两个指针的结构)。 要从另一个切片生成一个切片,需要分配一个切片并对每个切片进行转换 源切片的元素到目标切片的匹配元素

    最后,这意味着如果函数返回类型为
    []int
    的切片, 该切片不能直接由需要切片的代码处理 键入
    []接口{}
    (反之亦然),这就解释了原因 您问题中的两个函数签名表示不兼容 类型。

    表示
    []T
    []interface{}
    «在内存中没有相同的表示形式的状态

    为了理解原因,让我们分析两件事:

  • 片是一个后备存储器加上几个包含大小和容量的整数 那一片

    在Go中,数组并不是某种程度上的“高级”;相反地, 它们包含的元素的布局是严格定义的:它们都是 包含在一个相邻的内存区域中,彼此相邻

    这意味着,在片
    []T
    的后备数组中,元素是 键入
    T
    ,它们各自占据一个自然大小的内存区域 对于该类型
    T
    ,所有这些区域都彼此相邻 在单个连续内存块中

    这意味着,片
    []int
    的每个元素正好占用64位 (8字节)在64位平台上-单个
    int
    值的内存量 占据

  • 任何接口类型的值,包括空接口,
    接口{}
    表示为包含两个指针的结构, 比如:

    type iface struct {
        realType  *typeInfo
        realValue *dataType
    }
    
    (更多关于如何表示接口的信息-)

  • 上述所有方法都意味着在片
    []接口{}
    中,每个元素占用 内存区域两个指针的大小,这两个指针包含 内存中其他变量的地址-而不仅仅是整数值 包含在
    []int
    的元素中

    这反过来意味着你不能将
    []int
    “强制转换”到“
    []interface{}
    ”——仅仅因为
    []int
    (一个
    int
    )的任何元素中存储的值都是 其结构(内存布局)与元素不兼容 属于
    []接口{}
    (包含两个指针的结构)。 要从另一个切片生成一个切片,需要分配一个切片并对每个切片进行转换 源切片的元素到目标切片的匹配元素

    最后,这意味着如果函数返回类型为
    []int
    的切片, 该切片不能直接由需要切片的代码处理 键入
    []接口{}
    (反之亦然),这就解释了原因 您问题中的两个函数签名表示不兼容
    类型。

    这可能是重复的,但无论如何这应该有帮助:因为它们是不同类型的。从围棋常见问题解答:这可能是重复的,但无论如何这应该有帮助:因为它们是不同类型的。从围棋常见问题解答: