pointers - 为什么我不能使用指向需要 *interface{} 的特定类型的指针?

标签 pointers go typechecking

我有以下功能:

func bytesToData(data interface{}, b []byte) error {
    buf := bytes.NewBuffer(b)
    dec := gob.NewDecoder(buf)
    return dec.Decode(data)
}

我用它来获取进出 boltdb 的结构数据。我想做的是将该签名更改为:

func bytesToData(data *interface{}, b []byte) error

然后我希望能够像这样调用它(b 在这种情况下是一个 gob 编码的 Account)

acc := &Account{}
err := bytesToData(acc, b)

但是当我这样做时,我收到了类似Cannot use *Account for type *interface{} 的错误。

目前,我只是将其改回interface{}。但是,如果我直接传入 Account 或其他类型而不将其设为指针,gob 就会抛出错误。看起来这应该在编译时是可检查的。鉴于 interface{} 类型的参数接受任何内容,为什么 *interface{} 类型的参数不接受指向任何内容的指针?

最佳答案

Go 中接口(interface)类型的通用性不会传递给派生类型。这适用于指针(如您所见),也适用于 slice 、 channel 等。例如,您不能分配 []string。到 []interface{} .

有多种方法可以解释这一点。对于 Haskell 程序员:

Go 没有协变或逆变类型。所有类型构造函数(例如创建指针类型的 *)都是不变的。所以即使Account*Account (和所有其他类型)是 interface{} 的子类型, nothing 是 *interface{} 的子类型或 []interface{} .这有时很不方便,但它使 Go 的类型系统和可分配性规则更加简单。

对于 C 程序员:

interface{}可以保存任何类型的值,但它不直接保存它。它不是一个可变大小的魔术容器,而只是一个由指向类型的指针和指向值的指针组成的结构。当您将具体类型分配给 interface{} , 这两个字段都已填写。 *interface{}是指向这些结构之一的指针。当您尝试分配 *Account*interface{} ,没有地方可以放置类型信息,因为 *interface{}是一个只包含一个指针的机器字。所以编译器不会让你这样做。

关于pointers - 为什么我不能使用指向需要 *interface{} 的特定类型的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44864790/

相关文章:

php - 是否可以在 PHP 中使用指针?

c++ - 关闭应用程序是否释放在 C++ 中使用 new 分配的空间?

json - 想要发送空 json 字符串 "{}"而不是 "null"

debugging - Golang 调试功能

haskell - 为什么Haskell类型系统无法捕获这一点?

go - .(type) 在 go 中如何工作

c - 在 C 中将一维数组重新转换/转换为二维数组

c - 在C中没有指针的情况下在第二个字符串中查找第一个字符串

goroutine channels - send 语句的值

javascript - 功能的冗余类型检查?