上下文接口设计

我的问题是关于Context接口的设计选择。如果child要从中创建上下文,parent可以执行以下操作:

child, cancel := context.WithTimeout(parent, timeout)

如果WithTimeout是接口的一部分,那就更好了,这样我们可以简单地写:

child, cancel := parent.WithTimeout(timeout)

对我来说似乎干净得多。它更短,并且不需要import context

为什么产生子上下文的函数不是Context接口的一部分?

回答:

这是context.Context类型:

type Context interface {

Deadline() (deadline time.Time, ok bool)

Done() <-chan struct{}

Err() error

Value(key interface{}) interface{}

}

这很简单。如果要编写它的实现,可以这样做吗?是的,很容易。由于没有“设置”方法,因此每个方法都只能返回默认值/

零值,并且是“有效”的实现。这正是背景和TODO上下文(context.Background()context.TODO())所做的。

如果您要添加从现有环境(例如,等) 派生

新上下文的功能作为接口本身的一部分,则将需要为所有人提供(有效)实现,这是不可行的;而且几乎不需要同时使用它们,因此这会浪费资源。context.WithCancel()context.WithDeadline()Context

扩展负责添加实现。如果您查看context软件包的实现方式:context/context.gocontext.Context则将看到不同的“派生”或“扩展”的不同实现:

// An emptyCtx is never canceled, has no values, and has no deadline. It is not

// struct{}, since vars of this type must have distinct addresses.

type emptyCtx int

// A cancelCtx can be canceled. When canceled, it also cancels any children

// that implement canceler.

type cancelCtx struct {

Context

done chan struct{} // closed by the first cancel call.

mu sync.Mutex

children map[canceler]bool // set to nil by the first cancel call

err error // set to non-nil by the first cancel call

}

// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to

// implement Done and Err. It implements cancel by stopping its timer then

// delegating to cancelCtx.cancel.

type timerCtx struct {

cancelCtx

timer *time.Timer // Under cancelCtx.mu.

deadline time.Time

}

// A valueCtx carries a key-value pair. It implements Value for that key and

// delegates all other calls to the embedded Context.

type valueCtx struct {

Context

key, val interface{}

}

显然,我们可以弥补软件包context.Context中没有的其他有用扩展context。如果您有新想法,还可以将其添加到Context界面中吗?

这将破坏所有现有的实现 ,因为显然您的新想法未在其他人的当前实现中实现。

以上是 上下文接口设计 的全部内容, 来源链接: utcz.com/qa/399500.html

回到顶部