我在工作中讨论了接口名称和方法编号之间的关联。
特别是,关于接口的名称以er
结尾的后缀表示法存在一条未成文的规则。
规则说这样的接口应该包含一个方法。
让我们跳入一个例子。在标准的Go lang库中,有一个Pusher
接口,它做一件事“推送启动HTTP / 2服务器推送”。
这是它的定义:
type Pusher interface {
Push(target string, opts *PushOptions) error
}
https://golang.org/pkg/net/http/#Pusher
很好的例子。但是,一些同事为他的实现辩护,该实现包含名称后缀为er
的两个以上方法。
主要观点是,存在stdlib的接口违反了这样的规则。他提到了接口ReadCloser
。
查看其定义:
type ReadCloser interface {
Reader
Closer
}
https://golang.org/pkg/io/#ReadCloser
我可以说是错误的假设。接口本身嵌入了另外两个接口。我该怎么解释?不违反规则。
您将如何解释这种情况?
答案 0 :(得分:2)
这个问题可能会被关闭,因为它被认为是基于意见的,或者与代码无关,或者其他...
但是,golang被认为是很自以为是的,并且由于我认为标准非常重要,因此我将坚持不成文的规则,以及如何进行调和,从本质上讲ReadCloser
很好,但是其他一些er
接口可能不是。
我会解释ReadCloser
,不要违反“规则” (我将其称为惯例,更像是)。我有很多论点,为什么我会说它没有违反约定:
ReadCloser
接口不是一个独立的接口。这是一个组合界面。它的名字反映了这一点。它串联了Read
和Close
(您需要的接口中的2个功能),并添加了er
后缀。两种功能的实现方式以及它们的来源与接口无关。如果您阅读了一些内容,那么很有可能您也需要关闭资源。合并这两个接口才有意义,因此您可以使用保证Reader
和Closer
功能都可用的类型。
就像准则WRT package names那样,应该避免口吃。特别是如果它没有增加任何价值。从技术上讲,人们可能会争辩说应该将接口命名为ReaderCloser
,但是该名称是否传达了名称ReadCloser
中未传达的任何内容?当然不是。后者不再重复后缀,而且读起来更容易。
er
界面和CamelCasing 诸如er
或Stringer
之类的单功能Publisher
接口的例子确实很复杂。 Stringer
包含String
函数。故事结局。与Publisher
界面相同。
您会注意到ReadCloser
接口是CamelCased,表明它是一种复合类型。只需在UpperCase字符上拆分名称,然后将后缀添加到每个部分。如果部件是真正的er
接口,并且复合接口很有意义(请参阅第1点:如果您阅读,可能需要关闭),那么它是有效的复合接口。
无效的er
接口示例如下:
type FileReader interface {
ReadCloserer
ScanDir(string) ([]string, error)
IsFile(string) bool
Open(string, string) error
// and so on
}
此界面包含太多的BS功能,无法打包到FileReader
界面中。