【问题标题】:Go error: "embedded type cannot be a pointer to interface"Go 错误:“嵌入式类型不能是指向接口的指针”
【发布时间】:2016-11-09 08:47:23
【问题描述】:

以下代码给出编译时错误:

type IFile interface {
    Read() (n int, err error)
    Write() (n int, err error)
}

type TestFile struct {
   *IFile
}

错误:

./test.go:18: 嵌入式类型不能是指向接口的指针

为什么我不能嵌入*IFile

【问题讨论】:

  • 因为它是被禁止的。

标签: pointers go struct build interface


【解决方案1】:

语言规范不允许这样做。规范中的相关部分:Struct types:

使用类型声明但没有显式字段名称的字段是 匿名 字段,也称为 嵌入 字段或该类型在结构中的嵌入。嵌入类型必须指定为类型名称T指向非接口的指针 类型名称*T,而T 本身可能不是指针类型。非限定类型名称充当字段名称。

指向接口类型的指针很少有用,因为接口类型可能包含指针或非指针值。

话虽如此,如果实现你的IFile类型的具体类型是指针类型,那么指针值将被包装在IFile类型的接口值中,所以你仍然必须嵌入IFile,只是实现IFile 的值将是一个指针值,例如

// Let's say *FileImpl implements IFile:
f := TestFile{IFile: &FileImpl{}}

编辑:回复您的评论:

首先,这是 Go,而不是 C++。在 Go 中,接口不是指针,而是表示为一对(type;value),其中“值”可以是指针或非指针。更多信息请参见博文:The Laws of Reflection: The representation of an interface

其次,如果FileImpl 是一个类型,f := TestFile{IFile : &FileIml} 显然是编译时错误,你需要*FileImpl 的值,而&FileImpl 显然不是。例如,您需要一个composite literal,其形式为&FileImpl{},所以它应该是我在上面发布的。

【讨论】:

  • type IFile interface { Read() (n int, err error) Write() (n int, err error) } type FileImp { string file_name ..... } type TestFile struct { IFile } f := TestFile{IFile : FileIml} f 是否包含 FileImp 字段的内存副本?
  • @sotter f.IFile 字段是一个接口类型,它包含FileImpl 的副本,所以是的,f 包含FileImpl 的副本。如果您不希望那样,请使用 poitner,例如&FileImpl,因此只会存储指针的副本,但它会指向相同的 FileImpl 值。
  • 谢谢,我明白,但是,` f := TestFile{IFile : &FileIml}` 无法构建。在c++中,Interface是一个Pointer,所以我想在golang中type TestFile struct { *IFile}
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-16
  • 2019-05-04
  • 2012-11-24
  • 1970-01-01
  • 2011-12-18
  • 2016-08-01
  • 2019-07-07
相关资源
最近更新 更多