设为首页 加入收藏

TOP

带小伙伴手写 golang context(六)
2019-05-23 14:33:29 】 浏览:367
Tags:小伙伴 手写 golang context
t 包, 用于 golang 函数链安全的管理和控制.   

说真 golang context 实现非常漂亮, 代码中说明也事无巨细, 整体很赏心悦目.   

那我们带大家宏观过一遍 context 设计布局. 

// Context 上下文调用链条
type Context interface {
	// Deadline 返回是否完成和结束时刻
	Deadline() (deadline time.Time, ok bool)

	// Done 返回是否完成的阻塞 chan
	Done() (done <-chan struct{})

	// Err Done 时候储存 error 信息, Canceled or DeadlineExceeded
	Err() (err error)

	// Value Context 中获取 key 的值
	Value(key interface{}) (val interface{})
}

// emptyCtx 永远不会被取消的 context
type emptyCtx int

// cancelCtx 可被取消的 context
type cancelCtx struct { Context ... }

// timerCtx 带计时器和截止日期的 cancelCtx
type timerCtx struct { cancelCtx ... }

// valueCtx 储存键值对 context
type valueCtx struct {
	Context

	key, val interface{}
}

可以看出 Context 是个 interface, context.go 中有四种结构实现了 Context interface, 分别

是 emptyCtx, cancelCtx, timerCtx, valueCtx. 细看这类数据结构设计思路, 只记录父亲是谁,

单线联系. 可以反着类比普通树结构只记录儿子是谁哈哈, 大众货居然被玩出?, 真强.

 

正文 - context 手写

  废话不多说, 开始写代码. 上面 context.go 文件一把梭哈, 对于初学者还是无从学起的. 我们

这里按照结构分模式展开书写, 

├── context
│   ├── cancel.go
│   ├── context.go
│   ├── empty.go
│   ├── timer.go
│   ├── value.go
│   └── with.go

让其看起来好理解些. 

context.go 

package context

import (
	"errors"
	"time"
)

// Canceled 取消上下文时 context.Err 返回的错误
var Canceled = errors.New("context canceled")

// DeadlineExceeded 上下文超时时候 Context.Err 返回的错误
var DeadlineExceeded error = deadlineExceededError{}

type deadlineExceededError struct{}

func (deadlineExceededError) Error() string   { return "context deadline exceeded" }
func (deadlineExceededError) Timeout() bool   { return true }
func (deadlineExceededError) Temporary() bool { return true }

// Context 上下文调用链条
type Context interface {
	// Deadline 返回是否完成和结束时刻
	Deadline() (deadline time.Time, ok bool)

	// Done 返回是否完成的阻塞 chan
	Done() (done <-chan struct{})

	// Err Done 时候储存 error 信息, Canceled or DeadlineExceeded
	Err() (err error)

	// Value Context 中获取 key 的值
	Value(key interface{}) (val interface{})
}

empty.go

package context

import "time"

// emptyCtx 永远不会被取消的 context
type emptyCtx int

func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { return }
func (*emptyCtx) Done() (done <-chan struct{})            { return }
func (*emptyCtx) Err() (err error)                        { return }
func (*emptyCtx) Value(key interface{}) (val interface{}) { return }

var (
	background = new(emptyCtx)
	todo       = new(emptyCtx)
)

// String emptyCtx 打印方法
func (e *emptyCtx) String() string {
	switch e {
	case background:
		return "context.Background"
	case todo:
		return "context.TODO"
	}
	return "unknown empty Context"
}

// Background 不会被取消的 context, 一般用做顶级 context
func Background() Context {
	return background
}

// TODO 当你不知道用什么 Context 时候, 记住那就用这个
func TODO() Context {
	return todo
}

cancel.go 

package context

import (
	"reflect"
	"sync"
)

type stringer interface {
	String() string
}

func contextName(c Context) string {
	if s, ok := c.(stringer); ok {
		return s.String()
	}
	return reflect.TypeOf(c).String()
}

// canceler 可以直接取消的上下文, 详情见 *cancelCtx 和 *timerCtx
type canceler interface {
	cancel(removeFromParent bool, err error)
	Done() (done <-
首页 上一页 3 4 5 6 7 8 下一页 尾页 6/8/8
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇golang 变量定义 下一篇simple go web application & 二..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目