• What's new in Go 1.26

    Anton Zhiyanov • antonz.org

  • new(expr)

  • new(T)

    p1 := new(int)
    *p1 = 42
    fmt.Println(*p1)
    
    42
    
  • new(expr)

    p2 := new(42)
    fmt.Println(*p2)
    
    42
    
  • new(expr)

    type Cat struct {
        Name string `json:"name"`
        Fed  *bool  `json:"is_fed"`
    }
    
  • new(expr)

    type Cat struct {
        Name string `json:"name"`
        Fed  *bool  `json:"is_fed"`
    }
    
    cat := Cat{Name: "Mittens", Fed: new(true)}
    data, _ := json.Marshal(cat)
    fmt.Println(string(data))
    
    {"name":"Mittens","is_fed":true}
    
  • Type-safe error checking

  • errors.As

    var target *AppError
    if errors.As(err, &target) {
        fmt.Println("application error:", target)
    }
    
    application error: database is down
    
  • errors.AsType

    if target, ok := errors.AsType[*AppError](err); ok {
        fmt.Println("application error:", target)
    }
    
    application error: database is down
    
  • errors.AsType

    if connErr, ok := errors.AsType[*net.OpError](err); ok {
        fmt.Println("Network operation failed:", connErr.Op)
    } else if dnsErr, ok := errors.AsType[*net.DNSError](err); ok {
        fmt.Println("DNS resolution failed:", dnsErr.Name)
    } else {
        fmt.Println("Unknown error")
    }
    
    DNS resolution failed: antonz.org
    
  • errors.AsType

    if target, ok := errors.AsType[AppError](err); ok {
        fmt.Println("application error:", target)
    }
    
    AppError does not satisfy error (method Error has pointer receiver)
    
  • Green Tea garbage collector

  • Old GC

      ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
      ┃ [Obj A] ━━━━┓━━━━━━━━━━━━━━━━━━━┓                   ┃
      ┃          (jump)              [Obj E]                ┃
      ┃             ┃                   ┃                   ┃
      ┃ [Obj B] <━━━┛                 (jump)      [Obj G]   ┃
      ┃  ┃                              ┃            ┃      ┃
      ┃  ┗━━━━━━ (jump) ━━━━━━>[Obj D]<━┛          (jump)   ┃
      ┃             ┃             ┃ (jump)           ┃      ┃
      ┃ [Obj C]<━━━━┛             ┗━━━━━━━>[Obj F] ━━┛      ┃
      ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
    
  • Green Tea

      Memory span layout
    
    0x0000          0x0020          0x0040          0x0060          0x2000
      ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━ ━ ━┓
      ┃   Object 1    ┃   Object 2    ┃   Object 3    ┃   Object 4    ┃ ... ┃
      ┃  (32 bytes)   ┃  (32 bytes)   ┃  (32 bytes)   ┃  (32 bytes)   ┃     ┃
      ┗━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━ ━ ━┛
      ^               ^               ^               ^
      ┃               ┃               ┃               ┃
      ┗━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━┻━━━━ pos = base + idx*32
    
  • Green Tea

       32-byte objects          64-byte objects         128-byte objects
    ┏━━━━━━━━━━━━━━━━━━━━━┓  ┏━━━━━━━━━━━━━━━━━━━━━┓  ┏━━━━━━━━━━━━━━━━━━━━━┓
    ┃ ┌─────┐ ┌─────┐     ┃  ┃ ┌─────┐ ┌─────┐     ┃  ┃ ┌─────┐ ┌─────┐     ┃
    ┃ │Obj A│ │Obj C│     ┃  ┃ │Obj E│ │Obj G│     ┃  ┃ │Obj I│ │Obj K│     ┃
    ┃ └─────┘ └─────┘     ┃  ┃ └─────┘ └─────┘     ┃  ┃ └─────┘ └─────┘     ┃
    ┃ ┌─────┐ ┌─────┐     ┃  ┃ ┌─────┐ ┌─────┐     ┃  ┃ ┌─────┐ ┌─────┐     ┃
    ┃ │Obj B│ │Obj D│ ... ┃  ┃ │Obj F│ │Obj H│ ... ┃  ┃ │Obj G│ │Obj L│ ... ┃
    ┃ └─────┘ └─────┘     ┃  ┃ └─────┘ └─────┘     ┃  ┃ └─────┘ └─────┘     ┃
    ┗━━━━━━━━━━┳━━━━━━━━━━┛  ┗━━━━━━━━━━━━━━━━━━━━━┛  ┗━━━━━━━━━━━━━━━━━━━━━┛
          8 KiB span
    
  • Modernized go fix

  • go vet · go fix

  • go fix

    go fix [-fixtool prog] [-diff] [packages]
    
    any          mapsloop    reflecttypefor   stringcutprefix
    bloop        minmax      slicescontains   stringsseq
    fmtappendf   newexpr     slicessort       testingcontext
    forvar       omitzero    stditerators     waitgroup
    hostport     plusbuild   stringsbuilder
    inline       rangeint    stringscut
    
  • go fix

    var wg sync.WaitGroup
    
    wg.Add(1)
    go func() {
        defer wg.Done()
        // ...
    }()
    
    wg.Add(1)
    go func() {
        defer wg.Done()
        // ...
    }()
    
    wg.Wait()
    
  • go fix

    go fix -waitgroup .
    
    var wg sync.WaitGroup
    wg.Go(func() {
        // ...
    })
    wg.Go(func() {
        // ...
    })
    wg.Wait()
    
  • And many more

    Vectorized operations

    Secret mode

    Goroutine leak profile

    Goroutine metrics

    ...

  • Thank you!

    antonz.org/go-1-26