Why does `context.go` define and implement the `Context` interface?

huangapple go评论77阅读模式
英文:

Why does `context.go` define and implement the `Context` interface?

问题

Golang CodeReviewComments的接口部分中指出:

> Go的接口通常应该放在使用该接口类型值的包中,而不是实现这些值的包中。实现接口的包应该返回具体的(通常是指针或结构体)类型:这样,可以在不需要进行大量重构的情况下添加新的方法。

然而,Go的context.go模块既定义了Context接口,也为type emptyCtx inttype 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 接口,但也定义了 TCPListenerUDPListenerUnixListener。在这种情况下,将功能放在另一个包中是不合逻辑的。

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.

huangapple
  • 本文由 发表于 2021年11月22日 02:36:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/70057500.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定