为啥可以将切片分配给空接口但不能将其强制转换为相同的空接口

Posted

技术标签:

【中文标题】为啥可以将切片分配给空接口但不能将其强制转换为相同的空接口【英文标题】:Why can you assign a slice to an empty interface but not cast it to the same empty interface为什么可以将切片分配给空接口但不能将其强制转换为相同的空接口 【发布时间】:2022-01-19 10:35:26 【问题描述】:

为什么 golang 不支持将切片转换为空接口?但是,您可以通过将具有空接口的变量声明为类型并将切片分配给该变量来解决它。为什么它们不一样?

示例:https://play.golang.com/p/r4LXmR4JhF0

【问题讨论】:

Go 根本不支持转换 您是类型断言,而不是强制转换。这是完全不同的东西。请再次完成 Tour of Go 以了解此类基础知识。您的 slice 不是接口类型,这不能按类型断言。 【参考方案1】:

首先,Go 根本不支持转换

Go* 中根本没有类型转换。

您尝试做的是类型断言。

您的尝试失败有两个原因。两者都由编译器解释:

    invalid type assertion: slice.(<inter>) (non-interface type []interface on left)

    您不能将任何非接口类型声明为接口。

    non-name *castedSlice on left side of :=

    *castedSlice 在此上下文中无效。

如果要将切片存储在interface 类型的变量中,则赋值是正确的方法。您可以通过以下几种方式做到这一点:

    正如您所发现的,这是可行的:

    var result interface
    result = slice
    

    你可以结合这两行:

    var result interface = slice
    

    你也可以做一个简短的变量声明:

    result := interfaceslice
    

*以免有人挑剔声明:使用 unsafe 包在技术上可以完成与 Go 中的类型转换相同的操作,但由于这超出了语言规范,并且根据定义,不安全,我认为 Go 不支持类型转换仍然是一个合理的说法。

【讨论】:

因此,如果我正确理解了这一点,go 的作用如下:它将一些有关底层值的元数据保存在接口中。正因为如此,它可以断言接口 foo 是“可分配的”来键入 foobar?但是,既然 map 不是接口,它就不能断言呢? 我不确定地图如何适合这个讨论,但您只能键入 assert from 一个接口。这在spec 和A Tour of Go 中有解释。

以上是关于为啥可以将切片分配给空接口但不能将其强制转换为相同的空接口的主要内容,如果未能解决你的问题,请参考以下文章

为啥分配给空列表(例如 [] = "")不会出错?

为啥不能将不完整的类型强制转换为 void?

为啥我不能将其转换为自定义的 React 钩子?

父类对象是不是可以强制转换成子类的对象?为啥?

为啥我不能用 `copy()` 复制切片?

为啥 math.inf 是浮点数,为啥我不能将其转换为整数?