【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 记录原因
相关推荐
devilnumber16 小时前
Java 递归算法 详解 + 核心要点 + 实战运用 + 避坑指南
java·开发语言·算法
asdfg125896317 小时前
JavaBean是什么?怎么理解?有什么用途?
java·开发语言
dsyyyyy110118 小时前
JavaScript变量
开发语言·javascript·ecmascript
z落落19 小时前
C#WinForm 窗体切换与窗体传值(登录跳转案例)+WinForm 窗体传值(从上往下传、从下往上传)
开发语言·windows·c#
allway219 小时前
How to Echo Multiline to a File in Bash [3 Methods]
开发语言·chrome·bash
weixin_4624462319 小时前
手把手教你用 Bash 脚本自动更新 /etc/hosts —— 自动绑定网卡 IP 与节点名
开发语言·tcp/ip·bash
一个梦醒了19 小时前
安装git bash选项推荐
开发语言·git·bash
ct97819 小时前
React 状态管理方案深度对比
开发语言·前端·react
数量技术宅20 小时前
2026量化前沿:从Reddit热帖到Python实战,如何用赫斯特指数(Hurst)狙击虚假突破?
开发语言·python
华如锦20 小时前
面了很多 Java转AI Agent方向,一些面试题总结
java·开发语言·人工智能·python·ai