【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 小时前
Python语言的执行流程总结
开发语言·python
民乐团扒谱机2 小时前
【超详解】量子克拉美罗下界QCRB:时延估计精度极限推导+MATLAB多场景绘图实战
开发语言·机器学习·matlab·量子力学·qcrb
乐观勇敢坚强的老彭2 小时前
C++ 竞赛常用算法模板速查表
开发语言·c++·算法
圣殿骑士-Khtangc2 小时前
Go错误处理最佳实践进阶从error到panic的完整指南
golang
离陌在学C#2 小时前
C# 泛型:从基础到高级应用
开发语言·c#
ly76892 小时前
Java 设计模式详解:从原则到 23 种经典模式
java·开发语言·设计模式
SomeB1oody3 小时前
【RustyML入门】2.13. 孤立森林
开发语言·后端·机器学习·rust·教程
萧瑟余晖3 小时前
Java深入解析篇三十之Java日志框架
java·开发语言
Herbert_hwt3 小时前
【C语言基础】常量、选择结构与运算符全解析
c语言·开发语言·算法
运维开发笔记3 小时前
3.6 Go defer 语句学习笔记
golang