본문 바로가기
Backend2026년 4월 23일7분 읽기

Go 1.24 실전 — generics·sync.OnceFunc·HTTP/3·timer 개선

YS
김영삼
조회 1
Go 1.24 실전 — generics·sync.OnceFunc·HTTP/3·timer 개선

핵심 요약

Go 1.24는 변화가 많지 않지만 실용적인 개선이 다수. generic alias로 타입 코드 단순화, sync 새 API로 once 패턴 표준화, time.Timer 메모리 누수 해결, HTTP/3 net/http 통합 등.

  • 출시: 2026-02
  • generic alias 정식 지원
  • sync.OnceFunc·OnceValue·OnceValues
  • weak.Pointer (메모리 안전)
  • HTTP/3 net/http 통합 (실험)

1. Generic Alias

// 1.24부터 가능
type Stack[T any] = []T

var s Stack[int]  // []int와 동일

이전엔 type alias가 generic 받지 못했음. 라이브러리 설계가 깔끔해짐.

2. sync.OnceFunc·OnceValue·OnceValues

// 이전 패턴 — 직접 once 구현
var (
    once   sync.Once
    config *Config
)
func GetConfig() *Config {
    once.Do(func() {
        config = loadConfig()
    })
    return config
}

// 1.24 — sync.OnceValue
var GetConfig = sync.OnceValue(loadConfig)

// 사용
config := GetConfig()  // 첫 호출만 loadConfig 실행
// 여러 반환값
var GetUser = sync.OnceValues(func() (*User, error) {
    return fetchUser()
})

user, err := GetUser()

// 함수 자체
var Init = sync.OnceFunc(initialize)
Init()  // 첫 호출만 initialize 실행

3. time.Timer GC 개선

// 1.23 이전 — Timer가 GC 안 됨, Stop() 필수
timer := time.NewTimer(time.Hour)
defer timer.Stop()  // 잊으면 1시간 동안 메모리

// 1.24+ — Stop 안 해도 GC 됨
timer := time.NewTimer(time.Hour)
// reference 끊어지면 자동 GC

4. weak.Pointer

import "weak"

type Cache struct {
    items map[string]weak.Pointer[Item]
}

func (c *Cache) Get(key string) *Item {
    p := c.items[key]
    return p.Value()  // GC된 경우 nil
}

캐시 구현에서 메모리 누수 위험 없이 약한 참조. 다른 곳에서 참조 안 하면 GC.

5. HTTP/3 (실험)

import "net/http"

srv := &http.Server{
    Addr: ":443",
    Handler: mux,
}
srv.ListenAndServeQUIC(certFile, keyFile)  // HTTP/3

QUIC + UDP. 모바일·고지연 네트워크에서 큰 효과.

6. 실용적 패턴 — Singleton with sync.OnceValue

// db.go
package db

import (
    "sync"
    "database/sql"
    _ "github.com/lib/pq"
)

var getDB = sync.OnceValue(func() *sql.DB {
    db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
    if err != nil { panic(err) }
    db.SetMaxOpenConns(50)
    return db
})

func DB() *sql.DB { return getDB() }

7. range over function (1.23+)

// 1.23부터 도입, 1.24에서 안정화
func walk(root *Tree) func(yield func(int) bool) {
    return func(yield func(int) bool) {
        if root == nil { return }
        if !yield(root.Value) { return }
        for n := walk(root.Left); ; {
            // ...
        }
    }
}

// 사용
for v := range walk(tree) {
    fmt.Println(v)
}

8. swiss table (map 구현 변경)

1.24부터 map 내부가 swiss table로 변경. 평균 30% 빠름. 코드 변경 불필요.

9. log/slog 안정화

import "log/slog"

slog.Info("user logged in", "user_id", 123, "ip", "1.2.3.4")
// {"time":"...", "level":"INFO", "msg":"user logged in", "user_id":123, ...}

// 핸들러 커스터마이즈
h := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})
slog.SetDefault(slog.New(h))

10. 도구 개선

go test -json 표준

go test -json ./... | tee result.json
# JSON 출력 → CI에서 정확한 파싱 가능

go vet 더 엄격

새 검사: nil pointer, struct field tag, error wrapping. CI에 추가 권장.

11. 마이그레이션 1.23 → 1.24

  • go.mod의 go 1.24 명시
  • generic alias 적극 도입
  • sync.Once 패턴 → OnceValue로
  • time.Timer Stop() 호출 줄여도 됨 (단 명시는 안전)
  • map 성능 개선 자동

실측 — 1.22 vs 1.24

워크로드1.221.24
map heavy 워크로드baseline+30%
HTTP 서버 (단순)baseline+10%
JSON marshalbaseline+8%
메모리 (idle)baseline-12%

자주 묻는 질문

HTTP/3 운영 안정성?실험적. 운영 도입은 1.25 이후 권장. 일부 CDN(Cloudflare)에선 fronting으로 활용 가능.

generic alias가 기존 코드 영향?없음. 기존 type alias 그대로. 새로 generic alias 사용 가능.

sync.Once vs OnceValue?OnceValue는 값 반환·에러 처리 깔끔. 단순 한 번 실행은 OnceFunc. once 직접 쓰는 패턴은 거의 사라짐.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록