为什么我们不能在Go的接口中有属性?

为什么我们不能在Go的接口中有属性?,go,interface,Go,Interface,我理解您不能这样做,并且理解接口在Go中是如何工作的。但我主要关心的是为什么决定接口不能声明字段 我甚至可以看到一个建议,将其添加到Go V2 有人能对此给出一个明确的解释吗?一个原因,正如沃尔克在他留下的评论中如此准确地指出的那样:接口只封装行为。数据不是行为 另一个更容易理解的原因是:测试。目前,接口仅指定一组行为。假设我有一些需要测试的代码,需要编写器接口。如果某个笨手笨脚的开发人员实现了如下接口: type Writer interface { F *os.File Wr

我理解您不能这样做,并且理解接口在Go中是如何工作的。但我主要关心的是为什么决定接口不能声明字段

我甚至可以看到一个建议,将其添加到Go V2


有人能对此给出一个明确的解释吗?

一个原因,正如沃尔克在他留下的评论中如此准确地指出的那样:接口只封装行为。数据不是行为

另一个更容易理解的原因是:测试。目前,接口仅指定一组行为。假设我有一些需要测试的代码,需要编写器接口。如果某个笨手笨脚的开发人员实现了如下接口:

type Writer interface {
    F *os.File
    Write(b []bytes) (int, error)
}
type ComplexInterface interface {
   Engine *mypkg.SomeComplexType
   Client *grpc.Client
   // and so on
}
然后我需要一个模拟类型,它有一个文件指针,我可能无法将其保留为nil,因为我调用的代码应该可以使用该接口。这本身就很可怕。当然,创建临时文件很容易

现在,像这样的界面如何:

type Writer interface {
    F *os.File
    Write(b []bytes) (int, error)
}
type ComplexInterface interface {
   Engine *mypkg.SomeComplexType
   Client *grpc.Client
   // and so on
}
我需要创建一个复杂类型实例,它可能有20个依赖项。。。上帝只知道更改任何接口可能会变得多么昂贵。如果mypkg.SomeComplexType发生更改,那么我很快就会发现另一个包中的测试开始中断,因为我创建了一个非常紧密的耦合

是的:接口定义了行为,添加属性引入了大量的风险接口,如伪泛型、紧耦合、维护地狱等等

无论哪种方式,如果您希望在接口中使用属性,为什么不简单地编写以下内容:

type MyWriter interface {
    File() *os.File
    Write(b []bytes) (int, error)
}

用一个属性替换一个getter。工作完成。

此问题基于意见,属于Go作者。阅读提案讨论的一些原因:@icza感谢您的回复。虽然我确实认为这是基于观点的,但它不是主观的,而是技术上的自以为是。这种决定必须有技术上的优势和劣势。我只是想理解这些。接口只封装行为。数据不是行为。此外,接口可以由结构类型以外的类型实现,但只有结构类型可以有字段。此外,从接口定义隐藏数据允许在go 1.XX中实现泛型解决方案,即不支持泛型的情况。暴露特定的具体类型会降低界面的灵活性。非常感谢您的回答。它澄清了很多。