英文:
Why does `context.go` define and implement the `Context` interface?
问题
Golang CodeReviewComments的接口部分
中指出:
> Go的接口通常应该放在使用该接口类型值的包中,而不是实现这些值的包中。实现接口的包应该返回具体的(通常是指针或结构体)类型:这样,可以在不需要进行大量重构的情况下添加新的方法。
然而,Go的context.go
模块既定义了Context
接口,也为type emptyCtx int
和type cancelCtx struct
实现了该接口。
需要注意的是,上述部分说它们“通常”应该放在使用接口类型值的包中,所以我理解这不是一个严格的规定。
然而,我很好奇的是,使得它们在context
包中这样做是可以接受的标准是什么。
此外,这假设CodeReviewComments
是Go代码审查和样式指南的权威资源。
英文:
The interfaces portion of Golang CodeReviewComments
states:
> Go interfaces generally belong in the package that uses values of the interface type, not the package that implements those values. The implementing package should return concrete (usually pointer or struct) types: that way, new methods can be added to implementations without requiring extensive refactoring.
Yet, Go's context.go
module both defines the Context
interface and implements it for type emptyCtx int
and type cancelCtx struct
.
Note, the portion listed above says they "generally" belong in the package that uses values of the interface type — so I understand that this is not a strict rule.
However, I am curious as to what the criteria is that makes it OK for them to do this in the context
package.
Also, this assumes CodeReviewComments
is a canonical resource for Go code reviews and style guide.
答案1
得分: 4
在同一个包中定义接口的实现是相当常见的,特别是在实现策略模式或责任链模式(如上下文)时。
以 net 包为例,它定义了 Listener
接口,但也定义了 TCPListener
、UDPListener
和 UnixListener
。在这种情况下,将功能放在另一个包中是不合逻辑的。
io 包在读写器方面也采用了类似的做法。
另一个方便的模式是为只有一个函数的接口定义函数别名。就像 HandlerFunc 实现了 Handler,允许用户将闭包转换为 HandlerFunc,这样他们就不必定义自己的类型,这样做更加繁琐。
英文:
Defining implementations of an interface in the same package is actually pretty common, especially when implementing a strategy pattern or chain of responsibility(like context).
Take the net package for example, it defines the Listener
interface, but also TCPListener
, UDPListener
, and UnixListener
. In this case it would be illogical to place the functionality in another package.
The io package does a similar thing with the readers and writers.
Another handy pattern is to define a function alias for interfaces which only have 1 function. Like how HandlerFunc implements Handler, allowing users to cast closures as HandlerFunc so they don't have to define their own type, which is much more work.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论