【Go 1.26.4】(Part 8) Go 1.26.4 超深度分析 — context + reflect + errors

Go 1.26.4 超深度分析 --- context + reflect + errors

核心源码:context/context.go (806行) + reflect/type.go (2939行) + reflect/value.go (3865行) + errors/errors.go + errors/wrap.go


一、context --- 上下文传播

1.1 模块定位

context 包实现请求级的取消/超时/值传播

  • 跨 goroutine 取消信号传播
  • 跨 API 边界传递截止时间
  • 请求级数据传递(非参数传递)

1.2 Context 接口

go 复制代码
type Context interface {
    Deadline() (deadline time.Time, ok bool)  // 截止时间
    Done() <-chan struct{}                      // 取消信号
    Err() error                                 // 取消原因
    Value(key any) any                          // 请求级值
}

1.3 四种实现

类型 功能 创建函数
emptyCtx 空实现(永不取消) context.Background() / TODO()
cancelCtx 可取消 WithCancel(parent)
timerCtx 可取消+截止时间 WithDeadline/WithTimeout(parent)
valueCtx 携带值 WithValue(parent, key, val)

#mermaid-svg-uXi4PWlj5NI6dJYq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-uXi4PWlj5NI6dJYq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-uXi4PWlj5NI6dJYq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-uXi4PWlj5NI6dJYq .error-icon{fill:#552222;}#mermaid-svg-uXi4PWlj5NI6dJYq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-uXi4PWlj5NI6dJYq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-uXi4PWlj5NI6dJYq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-uXi4PWlj5NI6dJYq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-uXi4PWlj5NI6dJYq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-uXi4PWlj5NI6dJYq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-uXi4PWlj5NI6dJYq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-uXi4PWlj5NI6dJYq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-uXi4PWlj5NI6dJYq .marker.cross{stroke:#333333;}#mermaid-svg-uXi4PWlj5NI6dJYq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-uXi4PWlj5NI6dJYq p{margin:0;}#mermaid-svg-uXi4PWlj5NI6dJYq g.classGroup text{fill:#9370DB;stroke:none;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-uXi4PWlj5NI6dJYq g.classGroup text .title{font-weight:bolder;}#mermaid-svg-uXi4PWlj5NI6dJYq .cluster-label text{fill:#333;}#mermaid-svg-uXi4PWlj5NI6dJYq .cluster-label span{color:#333;}#mermaid-svg-uXi4PWlj5NI6dJYq .cluster-label span p{background-color:transparent;}#mermaid-svg-uXi4PWlj5NI6dJYq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-uXi4PWlj5NI6dJYq .cluster text{fill:#333;}#mermaid-svg-uXi4PWlj5NI6dJYq .cluster span{color:#333;}#mermaid-svg-uXi4PWlj5NI6dJYq .nodeLabel,#mermaid-svg-uXi4PWlj5NI6dJYq .edgeLabel{color:#131300;}#mermaid-svg-uXi4PWlj5NI6dJYq .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-uXi4PWlj5NI6dJYq .label text{fill:#131300;}#mermaid-svg-uXi4PWlj5NI6dJYq .labelBkg{background:#ECECFF;}#mermaid-svg-uXi4PWlj5NI6dJYq .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-uXi4PWlj5NI6dJYq .classTitle{font-weight:bolder;}#mermaid-svg-uXi4PWlj5NI6dJYq .node rect,#mermaid-svg-uXi4PWlj5NI6dJYq .node circle,#mermaid-svg-uXi4PWlj5NI6dJYq .node ellipse,#mermaid-svg-uXi4PWlj5NI6dJYq .node polygon,#mermaid-svg-uXi4PWlj5NI6dJYq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-uXi4PWlj5NI6dJYq .divider{stroke:#9370DB;stroke-width:1;}#mermaid-svg-uXi4PWlj5NI6dJYq g.clickable{cursor:pointer;}#mermaid-svg-uXi4PWlj5NI6dJYq g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-uXi4PWlj5NI6dJYq g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-uXi4PWlj5NI6dJYq .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-uXi4PWlj5NI6dJYq .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-uXi4PWlj5NI6dJYq .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-uXi4PWlj5NI6dJYq .dashed-line{stroke-dasharray:3;}#mermaid-svg-uXi4PWlj5NI6dJYq .dotted-line{stroke-dasharray:1 2;}#mermaid-svg-uXi4PWlj5NI6dJYq #compositionStart,#mermaid-svg-uXi4PWlj5NI6dJYq .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-uXi4PWlj5NI6dJYq #compositionEnd,#mermaid-svg-uXi4PWlj5NI6dJYq .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-uXi4PWlj5NI6dJYq #dependencyStart,#mermaid-svg-uXi4PWlj5NI6dJYq .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-uXi4PWlj5NI6dJYq #dependencyStart,#mermaid-svg-uXi4PWlj5NI6dJYq .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-uXi4PWlj5NI6dJYq #extensionStart,#mermaid-svg-uXi4PWlj5NI6dJYq .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-uXi4PWlj5NI6dJYq #extensionEnd,#mermaid-svg-uXi4PWlj5NI6dJYq .extension{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-uXi4PWlj5NI6dJYq #aggregationStart,#mermaid-svg-uXi4PWlj5NI6dJYq .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-uXi4PWlj5NI6dJYq #aggregationEnd,#mermaid-svg-uXi4PWlj5NI6dJYq .aggregation{fill:transparent!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-uXi4PWlj5NI6dJYq #lollipopStart,#mermaid-svg-uXi4PWlj5NI6dJYq .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-uXi4PWlj5NI6dJYq #lollipopEnd,#mermaid-svg-uXi4PWlj5NI6dJYq .lollipop{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-uXi4PWlj5NI6dJYq .edgeTerminals{font-size:11px;line-height:initial;}#mermaid-svg-uXi4PWlj5NI6dJYq .classTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-uXi4PWlj5NI6dJYq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-uXi4PWlj5NI6dJYq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-uXi4PWlj5NI6dJYq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} parent
embed
parent
<<interface>>
Context
+Deadline()(time.Time, bool)
+Done() : <-chan struct
+Err() : error
+Value(key any) : any
emptyCtx
+Deadline()(time.Time, false)
+Done() : nil
+Err() : nil
+Value(key) : nil
cancelCtx
-Context parent
-mu sync.Mutex
-done chan struct
-children mapcancelerstruct
-err error
+cancel(removeFromParent bool, err error)
timerCtx
-cancelCtx
-deadline time.Time
-timer *time.Timer
+Deadline()(time.Time, true)
valueCtx
-Context parent
-key, val any
+Value(key) : any

1.4 WithCancel --- 取消传播

go 复制代码
func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
    c := withCancelInput(parent)
    if c.done == nil {
        c = newCancelCtx(parent)
    }
    // 将自己加入 parent 的 children
    propagateCancel(parent, c)
    return c, func() { c.cancel(true, Canceled) }
}

propagateCancel --- 取消链建立

go 复制代码
func propagateCancel(parent Context, child canceler) {
    // 1. 如果 parent 已经取消 → 立即取消 child
    if parent.Done() == nil {
        return  // parent 永不取消 → 不需要传播
    }
    if parent.Err() != nil {
        child.cancel(false, parent.Err())  // parent 已取消
        return
    }

    // 2. 获取 parent 的 cancelCtx
    p, ok := parent.Value(&cancelCtxKey).(*cancelCtx)
    if !ok {
        // parent 不是 cancelCtx → 启动 goroutine 监听
        go func() {
            select {
            case <-parent.Done():
                child.cancel(false, parent.Err())
            case <-child.Done():
            }
        }()
        return
    }

    // 3. 将 child 加入 parent.children
    p.mu.Lock()
    if p.err != nil {
        p.mu.Unlock()
        child.cancel(false, p.err)  // parent 已取消
    } else {
        if p.children == nil {
            p.children = make(map[canceler]struct{})
        }
        p.children[child] = struct{}{}
        p.mu.Unlock()
    }
}

cancel --- 取消操作

go 复制代码
func (c *cancelCtx) cancel(removeFromParent bool, err error) {
    c.mu.Lock()
    if c.err != nil {
        c.mu.Unlock()
        return  // 已取消
    }
    c.err = err
    if c.done == nil {
        c.done = closedchan  // 复用已关闭的 channel
    } else {
        close(c.done)  // ★ 关闭 done channel → 所有监听者收到信号
    }

    // 递归取消所有 children
    for child := range c.children {
        child.cancel(false, err)
    }
    c.children = nil
    c.mu.Unlock()

    if removeFromParent {
        removeFromParent(c)  // 从 parent 的 children 中移除
    }
}

取消传播时序

Goroutine B Goroutine A Child2 Child1 Parent cancelCtx Goroutine B Goroutine A Child2 Child1 Parent cancelCtx #mermaid-svg-nZACRF5nVCY79MfV{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-nZACRF5nVCY79MfV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-nZACRF5nVCY79MfV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-nZACRF5nVCY79MfV .error-icon{fill:#552222;}#mermaid-svg-nZACRF5nVCY79MfV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-nZACRF5nVCY79MfV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-nZACRF5nVCY79MfV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-nZACRF5nVCY79MfV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-nZACRF5nVCY79MfV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-nZACRF5nVCY79MfV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-nZACRF5nVCY79MfV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-nZACRF5nVCY79MfV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-nZACRF5nVCY79MfV .marker.cross{stroke:#333333;}#mermaid-svg-nZACRF5nVCY79MfV svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-nZACRF5nVCY79MfV p{margin:0;}#mermaid-svg-nZACRF5nVCY79MfV .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-nZACRF5nVCY79MfV text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-nZACRF5nVCY79MfV .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-nZACRF5nVCY79MfV .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-nZACRF5nVCY79MfV .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-nZACRF5nVCY79MfV .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-nZACRF5nVCY79MfV #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-nZACRF5nVCY79MfV .sequenceNumber{fill:white;}#mermaid-svg-nZACRF5nVCY79MfV #sequencenumber{fill:#333;}#mermaid-svg-nZACRF5nVCY79MfV #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-nZACRF5nVCY79MfV .messageText{fill:#333;stroke:none;}#mermaid-svg-nZACRF5nVCY79MfV .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-nZACRF5nVCY79MfV .labelText,#mermaid-svg-nZACRF5nVCY79MfV .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-nZACRF5nVCY79MfV .loopText,#mermaid-svg-nZACRF5nVCY79MfV .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-nZACRF5nVCY79MfV .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-nZACRF5nVCY79MfV .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-nZACRF5nVCY79MfV .noteText,#mermaid-svg-nZACRF5nVCY79MfV .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-nZACRF5nVCY79MfV .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-nZACRF5nVCY79MfV .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-nZACRF5nVCY79MfV .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-nZACRF5nVCY79MfV .actorPopupMenu{position:absolute;}#mermaid-svg-nZACRF5nVCY79MfV .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-nZACRF5nVCY79MfV .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-nZACRF5nVCY79MfV .actor-man circle,#mermaid-svg-nZACRF5nVCY79MfV line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-nZACRF5nVCY79MfV :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} cancel() 被调用 propagateCancel → 加入 childrenpropagateCancel → 加入 children<-child1.Done() (阻塞)<-child2.Done() (阻塞)close(done)child1.cancel(false, err)child2.cancel(false, err)close(child1.done)close(child2.done)<-child1.Done() 收到信号<-child2.Done() 收到信号

1.5 WithDeadline --- 截止时间

go 复制代码
func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {
    // 如果 parent 的截止时间更早 → 不需要新 timer
    if cur, ok := parent.Deadline(); ok && cur.Before(d) {
        return WithCancel(parent)
    }

    c := &timerCtx{
        cancelCtx: newCancelCtx(parent),
        deadline:  d,
    }
    propagateCancel(parent, c)

    // 计算超时时间
    dur := time.Until(d)
    if dur <= 0 {
        c.cancel(true, DeadlineExceeded)  // 已超时
        return c, func() { c.cancel(false, Canceled) }
    }

    c.mu.Lock()
    defer c.mu.Unlock()
    if c.err == nil {
        c.timer = time.AfterFunc(dur, func() {
            c.cancel(true, DeadlineExceeded)
        })
    }
    return c, func() { c.cancel(true, Canceled) }
}

1.6 WithValue --- 值传递

go 复制代码
type valueCtx struct {
    Context
    key, val any
}

func (c *valueCtx) Value(key any) any {
    // 逐级向上查找
    if c.key == key {
        return c.val
    }
    return c.Context.Value(key)  // 递归查找 parent
}

设计要点:值查找是 O(深度) 链式查找,不适合高频使用。


二、reflect --- 运行时反射

2.1 模块定位

reflect 包实现运行时类型检查和值操作

  • TypeOf: 获取动态类型信息
  • ValueOf: 获取可操作的值
  • MakeFunc: 动态创建函数
  • DeepEqual: 深度比较

2.2 Type 接口

go 复制代码
type Type interface {
    Align() int
    FieldAlign() int
    Method(int) Method
    NumMethod() int
    Name() string
    PkgPath() string
    Size() uintptr
    String() string
    Kind() Kind
    Implements(u Type) bool
    AssignableTo(u Type) bool
    ConvertibleTo(u Type) bool
    NumField() int
    Field(i int) StructField
    Key() Type
    Elem() Type
    // ... 30+ 方法
}

2.3 rtype --- 底层类型表示

go 复制代码
type rtype struct {
    size       uintptr       // 类型大小
    ptrBytes   uintptr       // 指针占用的字节数
    hash       uint32        // 类型哈希
    tflag      tflag         // 类型标志
    align      uint8         // 对齐
    fieldAlign uint8         // 字段对齐
    kind       uint8         // Kind 枚举
    equal      func(unsafe.Pointer, unsafe.Pointer) bool  // 相等比较函数
    gcdata     unsafe.Pointer  // GC 数据
    str        nameOff       // 名称偏移
    ptrToThis  typeOff       // 指向此类型的指针类型偏移
}

2.4 Value 结构

go 复制代码
type Value struct {
    typ  *rtype          // 类型指针
    ptr  unsafe.Pointer  // 数据指针
    flag                // 标志位 (kind + flags)
}

flag 位图

位域 描述
flagKindMask 低位: Kind 枚举
flagStickyRO 粘性只读(未导出字段)
flagEmbedRO 嵌入只读(未导出嵌入字段)
flagIndir ptr 是间接指针(指向堆)
flagAddr 可取地址
flagMethod 是方法值

2.5 Value 核心方法

go 复制代码
func (v Value) Interface() any {
    // 将 Value 转回 interface{}
    return v.interface()
}

func (v Value) Elem() Value {
    // 解引用指针/接口/slice/array/map/channel
    ...
}

func (v Value) Field(i int) Value {
    // 获取结构体第 i 个字段
    ...
}

func (v Value) Call(in []Value) []Value {
    // 调用函数/方法
    ...
}

reflect.Value 操作链

#mermaid-svg-rEUhbyIqgMA48rJ5{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rEUhbyIqgMA48rJ5 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rEUhbyIqgMA48rJ5 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rEUhbyIqgMA48rJ5 .error-icon{fill:#552222;}#mermaid-svg-rEUhbyIqgMA48rJ5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rEUhbyIqgMA48rJ5 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rEUhbyIqgMA48rJ5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rEUhbyIqgMA48rJ5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rEUhbyIqgMA48rJ5 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rEUhbyIqgMA48rJ5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rEUhbyIqgMA48rJ5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rEUhbyIqgMA48rJ5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rEUhbyIqgMA48rJ5 .marker.cross{stroke:#333333;}#mermaid-svg-rEUhbyIqgMA48rJ5 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rEUhbyIqgMA48rJ5 p{margin:0;}#mermaid-svg-rEUhbyIqgMA48rJ5 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rEUhbyIqgMA48rJ5 .cluster-label text{fill:#333;}#mermaid-svg-rEUhbyIqgMA48rJ5 .cluster-label span{color:#333;}#mermaid-svg-rEUhbyIqgMA48rJ5 .cluster-label span p{background-color:transparent;}#mermaid-svg-rEUhbyIqgMA48rJ5 .label text,#mermaid-svg-rEUhbyIqgMA48rJ5 span{fill:#333;color:#333;}#mermaid-svg-rEUhbyIqgMA48rJ5 .node rect,#mermaid-svg-rEUhbyIqgMA48rJ5 .node circle,#mermaid-svg-rEUhbyIqgMA48rJ5 .node ellipse,#mermaid-svg-rEUhbyIqgMA48rJ5 .node polygon,#mermaid-svg-rEUhbyIqgMA48rJ5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rEUhbyIqgMA48rJ5 .rough-node .label text,#mermaid-svg-rEUhbyIqgMA48rJ5 .node .label text,#mermaid-svg-rEUhbyIqgMA48rJ5 .image-shape .label,#mermaid-svg-rEUhbyIqgMA48rJ5 .icon-shape .label{text-anchor:middle;}#mermaid-svg-rEUhbyIqgMA48rJ5 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rEUhbyIqgMA48rJ5 .rough-node .label,#mermaid-svg-rEUhbyIqgMA48rJ5 .node .label,#mermaid-svg-rEUhbyIqgMA48rJ5 .image-shape .label,#mermaid-svg-rEUhbyIqgMA48rJ5 .icon-shape .label{text-align:center;}#mermaid-svg-rEUhbyIqgMA48rJ5 .node.clickable{cursor:pointer;}#mermaid-svg-rEUhbyIqgMA48rJ5 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rEUhbyIqgMA48rJ5 .arrowheadPath{fill:#333333;}#mermaid-svg-rEUhbyIqgMA48rJ5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rEUhbyIqgMA48rJ5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rEUhbyIqgMA48rJ5 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rEUhbyIqgMA48rJ5 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rEUhbyIqgMA48rJ5 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rEUhbyIqgMA48rJ5 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rEUhbyIqgMA48rJ5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rEUhbyIqgMA48rJ5 .cluster text{fill:#333;}#mermaid-svg-rEUhbyIqgMA48rJ5 .cluster span{color:#333;}#mermaid-svg-rEUhbyIqgMA48rJ5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rEUhbyIqgMA48rJ5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rEUhbyIqgMA48rJ5 rect.text{fill:none;stroke-width:0;}#mermaid-svg-rEUhbyIqgMA48rJ5 .icon-shape,#mermaid-svg-rEUhbyIqgMA48rJ5 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rEUhbyIqgMA48rJ5 .icon-shape p,#mermaid-svg-rEUhbyIqgMA48rJ5 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rEUhbyIqgMA48rJ5 .icon-shape .label rect,#mermaid-svg-rEUhbyIqgMA48rJ5 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rEUhbyIqgMA48rJ5 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rEUhbyIqgMA48rJ5 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rEUhbyIqgMA48rJ5 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Ptr
Interface
reflect.ValueOf(x)
v.Type() → *rtype
v.Kind() → Kind枚举
v.Interface() → any
v.Elem() → 解引用
v.Field(i) → 字段
v.Call(args) → 调用
v.Set(x) → 赋值
指向的值
具体值
结构体字段Value
\[\]Value 返回值
修改后的值


三、errors --- 错误处理

3.1 errors.New

go 复制代码
func New(text string) error {
    return &errorString{text}
}

type errorString struct {
    s string
}

3.2 错误链 (Unwrap)

go 复制代码
// 单层 Unwrap
type wrapError struct {
    msg string
    err error
}

func (e *wrapError) Unwrap() error { return e.err }

// 多层 Unwrap (Go 1.20+)
type joinError struct {
    errs []error
}

func (e *joinError) Unwrap() []error { return e.errs }

3.3 Is/As --- 错误树遍历

go 复制代码
func Is(err, target error) bool {
    // 深度优先遍历错误树
    for {
        if err == target { return true }
        // 尝试 Unwrap() error
        if unwrapper, ok := err.(interface{ Unwrap() error }); ok {
            err = unwrapper.Unwrap()
            continue
        }
        // 尝试 Unwrap() []error
        if multi, ok := err.(interface{ Unwrap() []error }); ok {
            for _, e := range multi.Unwrap() {
                if Is(e, target) { return true }
            }
        }
        return false
    }
}

错误树遍历

#mermaid-svg-p05xMJ7Zxf6bGG4p{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-p05xMJ7Zxf6bGG4p .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-p05xMJ7Zxf6bGG4p .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-p05xMJ7Zxf6bGG4p .error-icon{fill:#552222;}#mermaid-svg-p05xMJ7Zxf6bGG4p .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-p05xMJ7Zxf6bGG4p .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-p05xMJ7Zxf6bGG4p .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-p05xMJ7Zxf6bGG4p .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-p05xMJ7Zxf6bGG4p .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-p05xMJ7Zxf6bGG4p .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-p05xMJ7Zxf6bGG4p .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-p05xMJ7Zxf6bGG4p .marker{fill:#333333;stroke:#333333;}#mermaid-svg-p05xMJ7Zxf6bGG4p .marker.cross{stroke:#333333;}#mermaid-svg-p05xMJ7Zxf6bGG4p svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-p05xMJ7Zxf6bGG4p p{margin:0;}#mermaid-svg-p05xMJ7Zxf6bGG4p .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-p05xMJ7Zxf6bGG4p .cluster-label text{fill:#333;}#mermaid-svg-p05xMJ7Zxf6bGG4p .cluster-label span{color:#333;}#mermaid-svg-p05xMJ7Zxf6bGG4p .cluster-label span p{background-color:transparent;}#mermaid-svg-p05xMJ7Zxf6bGG4p .label text,#mermaid-svg-p05xMJ7Zxf6bGG4p span{fill:#333;color:#333;}#mermaid-svg-p05xMJ7Zxf6bGG4p .node rect,#mermaid-svg-p05xMJ7Zxf6bGG4p .node circle,#mermaid-svg-p05xMJ7Zxf6bGG4p .node ellipse,#mermaid-svg-p05xMJ7Zxf6bGG4p .node polygon,#mermaid-svg-p05xMJ7Zxf6bGG4p .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-p05xMJ7Zxf6bGG4p .rough-node .label text,#mermaid-svg-p05xMJ7Zxf6bGG4p .node .label text,#mermaid-svg-p05xMJ7Zxf6bGG4p .image-shape .label,#mermaid-svg-p05xMJ7Zxf6bGG4p .icon-shape .label{text-anchor:middle;}#mermaid-svg-p05xMJ7Zxf6bGG4p .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-p05xMJ7Zxf6bGG4p .rough-node .label,#mermaid-svg-p05xMJ7Zxf6bGG4p .node .label,#mermaid-svg-p05xMJ7Zxf6bGG4p .image-shape .label,#mermaid-svg-p05xMJ7Zxf6bGG4p .icon-shape .label{text-align:center;}#mermaid-svg-p05xMJ7Zxf6bGG4p .node.clickable{cursor:pointer;}#mermaid-svg-p05xMJ7Zxf6bGG4p .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-p05xMJ7Zxf6bGG4p .arrowheadPath{fill:#333333;}#mermaid-svg-p05xMJ7Zxf6bGG4p .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-p05xMJ7Zxf6bGG4p .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-p05xMJ7Zxf6bGG4p .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-p05xMJ7Zxf6bGG4p .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-p05xMJ7Zxf6bGG4p .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-p05xMJ7Zxf6bGG4p .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-p05xMJ7Zxf6bGG4p .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-p05xMJ7Zxf6bGG4p .cluster text{fill:#333;}#mermaid-svg-p05xMJ7Zxf6bGG4p .cluster span{color:#333;}#mermaid-svg-p05xMJ7Zxf6bGG4p div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-p05xMJ7Zxf6bGG4p .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-p05xMJ7Zxf6bGG4p rect.text{fill:none;stroke-width:0;}#mermaid-svg-p05xMJ7Zxf6bGG4p .icon-shape,#mermaid-svg-p05xMJ7Zxf6bGG4p .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-p05xMJ7Zxf6bGG4p .icon-shape p,#mermaid-svg-p05xMJ7Zxf6bGG4p .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-p05xMJ7Zxf6bGG4p .icon-shape .label rect,#mermaid-svg-p05xMJ7Zxf6bGG4p .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-p05xMJ7Zxf6bGG4p .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-p05xMJ7Zxf6bGG4p .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-p05xMJ7Zxf6bGG4p :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} .Unwrap()
.Unwrap()
fmt.Errorf('wrap1: %w', err1)
err1 = fmt.Errorf('wrap2: %w', err2)
err2 = errors.New('base')
errors.Is(root, err2) → true
errors.Is(root, err1) → true


四、设计模式总结

# 模式 体现
1 组合模式 context: cancelCtx/timerCtx/valueCtx 嵌套
2 观察者模式 cancelCtx → children map 取消通知
3 闭 channel 信号 close(done) 广播取消
4 递归查找 valueCtx.Value 链式查找
5 延迟初始化 cancelCtx.done 延迟创建
6 接口多态 Context 接口 4 种实现
7 类型擦除 reflect.Type 对 Go 类型系统的抽象
8 位图标志 Value.flag kind+flags 编码
9 安全封装 Value 隐藏 unsafe.Pointer
10 错误链 Unwrap() 单/多 层遍历
11 深度优先 errors.Is/As 树遍历
12 Cause 语义 WithCancelCause/Cause 记录原因
相关推荐
黑马程序员毕设1 小时前
基于Java的医院药品管理系统的优化设计与实现
java·开发语言·spring boot·小程序·架构·课程设计·毕设
_Twink1e2 小时前
openJiuwen 实训营 Day 1 · WorkSwarm 入门教程
开发语言·c++·openjiuwen
问天_观心2 小时前
大模型微调学习(一)
开发语言·人工智能·学习·语言模型·github
阿里嘎多学长2 小时前
2026-09-03 GitHub 热点项目精选
开发语言·程序员·github·代码托管
FfHUCisI2 小时前
Golang Map 哈希表实现
golang·哈希算法·散列表
源代码•宸3 小时前
前置准备:定时微服务背景和现状
开发语言·经验分享·后端·微服务·云原生·架构·golang
2601_967338713 小时前
C#上位机开发零基础入门到精通全套视频
开发语言·c#
小白学大数据4 小时前
超简单:用 Python 让 Excel 飞起来:用 openpyxl 把重复报表整理交给脚本
开发语言·数据库·python·excel
旧梦95274 小时前
Java SortedMap 接口详解:从入门到实战
java·开发语言
莫陌尛.4 小时前
Java_this构造方法
java·开发语言