当前位置: 首页 > 面试题库 >

上下文接口设计

郗鹏
2023-03-14
问题内容

我的问题是关于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界面中吗?
这将破坏所有现有的实现 ,因为显然您的新想法未在其他人的当前实现中实现。



 类似资料:
  • 我有一个带有主窗口的应用程序。它有自己的线程和opengl上下文。这个应用程序每个处理器还有一个工作线程来创建和上传软件渲染的纹理。这工作得非常好。 我担心的是工作线程opengl上下文是使用主窗口的device_context创建的。因此,在双处理器系统的情况下,这意味着3个opengl上下文被绑定到同一个window device_context。它们都是在主窗口线程中创建的,然后调用shar

  • 1.1.1. 设备接口文档 1.1.1. 设备接口文档 1)调用方式 client http InternalService(grpc) ------------------------------------------------------------------------- http(带Authorization)

  • 问题内容: 上周受本文启发,我正在重构我必须更明确地将上下文(数据库池,会话存储等)传递给处理程序的应用程序。 但是,我遇到的一个问题是,如果没有全局模板映射,我的自定义处理程序类型(要满足)上的方法将无法再访问该映射以呈现模板。 我需要保留全局变量,或者将我的自定义处理程序类型重新定义为结构。 有没有更好的方法来实现这一目标? func.go struct.go 有没有更干净的方法将实例传递给?

  • 用法同WebSocket 服务器 - 会话数据

  • imi 中 WebSocket 服务中使用 Imi\ConnectContext 类对连接的会话数据进行管理。在整个连接的生命周期中都有效。 使用 use Imi\ConnectContext; // 取值 echo ConnectContext::get('name'); echo ConnectContext::get('name', 'default value'); // 赋值 Con

  • 接口设计 用户使用 Web 客户端访问 Web 系统,系统在收到请求后执行操作 (收集数据模型,选择数据经行组装),将结果返回给客户。 其中包括的元素和关系如下图所示: Template,分离数据模型的页面结构,根据不同的数据模型展现不同的信息 URL,页面访问地址、页面标示 API,用于载入异步请求的接口 Model,数据模型,页面模板组装模型和异步请求返回的数据模型 约定 URL 与页面模板间