【问题标题】:Should I embed interface from standard library or write my own?我应该从标准库嵌入接口还是自己编写?
【发布时间】:2022-01-16 22:21:17
【问题描述】:

Go 的标准库中有一些通用接口,例如 io.Closer:

type Closer interface {
    Close() error
}

如果我想在我的代码中定义一个具有Close 方法的接口,我会像这样嵌入io.Closer

type example interface {
    io.Closer

    // ... some other functions or embedded types
}

或者我会像这样定义函数本身:

type example interface {
    Close() error

    // ... some other functions or embedded types
}

这方面有什么最佳做法吗?

【问题讨论】:

标签: go interface


【解决方案1】:

对于这样常见且简单的接口,我肯定会从标准库中嵌入一个(例如io.Closerio.Readerio.ByteReader)。

但不是任何接口类型。一般来说,接口应该在需要的地方定义。嵌入在其他包(包括标准库)中定义的任何接口都有在更改或扩展时无法隐式实现它们的危险。

包的“所有者”(定义者)可能会更改它(例如,用新方法扩展它)并正确更新实现它的所有类型,因此包可以继续从外部工作,但显然包所有者不会更新您的实现。

例如reflect.Type 接口类型在Go 1.0 中没有Type.ConvertibleTo() 方法,它是在Go 1.1 中添加的。同样的事情也可能发生:标准库中的接口可能会在未来的 Go 版本中被更改或扩展,导致您现有的代码无法实现它们。

小型通用接口与“其他”接口有什么区别? 接口越大,抽象越弱——Go 谚语也是如此。像io.Closerio.Reader 这样的小接口捕获了一个微小但重要的功能。它们是如此普遍,“每个”库都试图实现它们,每个实用函数都建立在它们之上。我从没想过他们会改变。如果有理由更改/扩展它们,它们将被添加为新接口。不像更大的接口,抽象更难准确捕获。随着时间的推移,他们有更好的机会改变/发展。

【讨论】:

  • 您回答的第一段与您的以下解释有些矛盾。为什么io.Closer 应该是一般规则的例外?使用io.Closer 比使用Close() error 有什么好处?
猜你喜欢
  • 2011-08-01
  • 1970-01-01
  • 2011-03-23
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 2017-11-04
  • 1970-01-01
  • 2012-06-16
相关资源
最近更新 更多