我应该从标准库嵌入接口还是自己编写?
Should I embed interface from standard library or write my own?
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
}
对此有什么最佳实践吗?
对于这种通用和简单的接口,我肯定会嵌入标准库中的接口(例如 io.Closer
, io.Reader
and io.ByteReader
)。
但不是任何接口类型。一般来说,应该在需要的地方定义接口。嵌入在其他包(包括标准库)中定义的任何接口都有在更改或扩展时无法隐式实现它们的危险。
包的“所有者”(定义者)可能会更改它(例如用新方法扩展它)并正确更新实现它的所有类型,因此包可以继续从外部工作,但显然包所有者不会更新您的实现。
例如 reflect.Type
接口类型在 Go 1.0, it was added in Go 1.1 中没有 Type.ConvertibleTo()
方法。同样的事情可能会发生:标准库中的接口可能会在未来的 Go 版本中被更改或扩展,导致您现有的代码无法实现它们。
小型通用接口与“其余”接口有何区别? 接口越大,抽象越弱——Go 谚语也是如此。像 io.Closer
和 io.Reader
这样的小接口捕获了微小但重要的功能。它们是如此普遍,“每个”库都试图实现它们,每个实用程序函数都建立在它们之上。我从没想过他们会改变。如果有理由更改/扩展它们,它们将作为新接口添加。不像更大的接口,抽象更难准确捕获。随着时间的推移,他们有更好的机会改变/发展。
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
}
对此有什么最佳实践吗?
对于这种通用和简单的接口,我肯定会嵌入标准库中的接口(例如 io.Closer
, io.Reader
and io.ByteReader
)。
但不是任何接口类型。一般来说,应该在需要的地方定义接口。嵌入在其他包(包括标准库)中定义的任何接口都有在更改或扩展时无法隐式实现它们的危险。
包的“所有者”(定义者)可能会更改它(例如用新方法扩展它)并正确更新实现它的所有类型,因此包可以继续从外部工作,但显然包所有者不会更新您的实现。
例如 reflect.Type
接口类型在 Go 1.0, it was added in Go 1.1 中没有 Type.ConvertibleTo()
方法。同样的事情可能会发生:标准库中的接口可能会在未来的 Go 版本中被更改或扩展,导致您现有的代码无法实现它们。
小型通用接口与“其余”接口有何区别? 接口越大,抽象越弱——Go 谚语也是如此。像 io.Closer
和 io.Reader
这样的小接口捕获了微小但重要的功能。它们是如此普遍,“每个”库都试图实现它们,每个实用程序函数都建立在它们之上。我从没想过他们会改变。如果有理由更改/扩展它们,它们将作为新接口添加。不像更大的接口,抽象更难准确捕获。随着时间的推移,他们有更好的机会改变/发展。