Go 1.27 미리보기 — 제네릭 메서드가 드디어 온다
접수창구로 "go 1.27" 넉 자가 들어왔습니다. 정식 출시 전이라 뭘 정리하나 싶었는데, rc2 까지 나온 시점이면 릴리스 노트는 사실상 확정입니다. 어차피 8월 중순에 다시 볼 내용이라, 지금 한 번에 정리해 두고 정식 때는 안 움직이는 쪽을 택했습니다. 이하는 go1.27rc2 와 확정 단계의 릴리스 노트 초안 기준입니다.
어디까지 왔나#
Go 는 2월과 8월, 6개월 주기로 메이저 버전을 낸다. Go 1.26 이 2026년 2월 10일에 나왔으니 1.27 은 8월 중순이 예정 자리다. 릴리스 후보는 이미 두 번 나왔다. rc1 이 6월 18일, rc2 가 7월 7일이고, rc2 에는 os.Root 가 Unix 에서 심링크를 잘못 따라가던 문제를 포함한 보안 수정 2건이 들어갔다.
제네릭 메서드 — 4년 반 만에 채워지는 조각#
이번 릴리스의 헤드라인이다. Go 1.18(2022년 3월)이 제네릭을 도입할 때 의도적으로 빼놓았던 조각, 즉 메서드가 수신자와 별개로 자기만의 타입 파라미터를 선언하는 것이 1.27 에서 언어에 들어온다.
type Box[T any] struct{ v T }
// Map 이 수신자의 T 와 별개로 U 를 선언한다 — 1.26 까지는 불가능했다
func (b Box[T]) Map[U any](f func(T) U) Box[U] {
return Box[U]{v: f(b.v)}
}
지금까지는 이런 변환을 패키지 레벨 함수 Map(box, f) 로 쓸 수밖에 없어서, 타입에 속하는 연산이 타입 밖에 흩어졌다. 이제 box.Map(f) 로 붙는다. 제약은 하나 기억하면 된다. 인터페이스는 제네릭 메서드를 선언할 수 없고, 제네릭 메서드는 인터페이스 만족(method set)에 참여하지 않는다. 런타임에 임의 타입 인자로 메서드를 디스패치하는 문제를 피하기 위한 선긋기로, 제네릭 도입 당시 이 조각이 빠졌던 이유이기도 하다.
구조체 리터럴 쪽에도 작지만 체감이 큰 변화가 있다. 리터럴의 키에 최상위 필드명만 쓸 수 있던 제한이 풀려, 임베딩으로 승격된 필드를 바로 쓸 수 있다.
type Base struct{ ID int }
type User struct {
Base
Name string
}
u := User{Base: Base{ID: 7}, Name: "Mittens"} // 1.26 까지
u := User{ID: 7, Name: "Mittens"} // 1.27
필드를 임베딩 타입으로 리팩터링하는 순간 그 타입의 모든 리터럴이 깨지던 마찰이 사라진다.
encoding/json/v2 — 실험 꼬리표를 뗀다#
Go 1.25 에서 GOEXPERIMENT=jsonv2 뒤에 숨어 있던 encoding/json/v2 가 1.27 에서 기본 탑재된다. 표준 라이브러리 최초의 v2 패키지가 정식으로 서는 셈이다. v1 과의 차이는 "더 엄격하고 더 빠르다"로 요약된다.
- 잘못된 UTF-8 을 조용히 바꿔치기하지 않고 거부한다
- JSON 객체 안의 중복 키를 거부한다
- 언마샬 성능이 크게 개선됐다 (마샬은 v1 과 비슷한 수준)
- 저수준 토큰 처리는 새
encoding/json/jsontext패키지가 맡는다
기존 encoding/json 은 그대로 동작하므로 코드를 고칠 필요는 없다. 문제가 생기면 GOEXPERIMENT=nojsonv2 로 되돌릴 수 있다.
런타임 — 작은 할당이 최대 30% 빨라진다#
메모리 할당기가 크기별 특화 루틴을 갖게 됐다. 80바이트 미만의 작은 할당 비용이 최대 30% 줄고, 할당이 많은 실제 프로그램 기준 전체 성능은 1% 안팎 개선된다. 대가는 바이너리 크기 약 60KB 증가다. GOEXPERIMENT=nosizespecializedmalloc 으로 끌 수 있지만 이 스위치는 1.28 에서 없어질 예정이다.
디버깅 쪽에서는 goroutine leak profile 이 정식 기능이 됐다. GC 의 도달성 분석을 빌려, 채널·sync.Mutex·sync.Cond 등에서 영구히 블록된 고루틴을 찾아 스택과 함께 보고한다. runtime/pprof 의 goroutineleak 프로필 또는 /debug/pprof/goroutineleak 엔드포인트로 받는다. 고루틴 누수는 지금까지 "고루틴 수 그래프가 우상향이면 어딘가 샌다" 수준의 정황 증거로 잡던 문제라, 누수 지점을 스택으로 찍어 주는 프로파일은 실전 가치가 크다.
새 표준 라이브러리 — uuid, 포스트퀀텀, SIMD#
| 패키지 | 내용 |
|---|---|
uuid (신설) | UUID 생성·파싱이 표준에 들어왔다. 경로에 카테고리 없이 최상위 import "uuid" 다. 범용 New(), 순수 랜덤 NewV4(), 시간 정렬 가능해 DB 키에 맞는 NewV7() 을 제공한다 |
crypto/mldsa (신설) | 포스트퀀텀 서명 ML-DSA(FIPS 204). crypto/x509 의 키·서명, TLS 1.3 의 서명 스킴(MLDSA44/65/87)까지 함께 지원한다 |
simd, simd/archsimd (실험) | GOEXPERIMENT=simd 뒤의 명시적 SIMD API. 1.27 에서 amd64 API 를 개정하고 arm64 Neon 과 WebAssembly 의 128비트 SIMD 를 추가했다 |
strings·bytes | CutLast 추가. Cut 의 마지막 구분자 판이다. CutLast("a/b/c", "/") → "a/b", "c" |
net/url | URL.Clone()·Values.Clone(). URL 복사를 손으로 짜던 자리가 사라진다 |
unicode | Unicode 17 로 업그레이드 |
사라지는 것들#
더해지는 것만큼 지워지는 것도 있다.
asynctimerchanGODEBUG 가 완전히 제거됐다. 1.23 에서 바뀐 타이머 채널 동작(unbuffered·동기식)으로 돌아갈 마지막 탈출구가 닫힌 것이라, 옛 타이머 동작에 기대는 코드가 있다면 1.27 이전에 정리해야 한다- 구식 TLS 를 되살리던 GODEBUG 무리(
tls10server,tlsrsakex,tls3des등)도 함께 제거됐다 go명령의 Bazaar(bzr) 버전 관리 지원이 빠졌다go tool trace는-http=:6060처럼 호스트를 비우면 이제 localhost 에만 바인딩한다. 프로파일 서버가 사내망 전체에 열리던 기본값의 교정이다
정리하면서 보니 이번 판은 "큰 것 하나(제네릭 메서드) + 오래 묵힌 숙제 청산(json/v2 승격, GODEBUG 정리)"의 구성입니다. 업그레이드를 서두를 이유도, 두려워할 이유도 별로 없는 릴리스라는 뜻입니다. 프로덕션 워크로드가 있으면 go1.27rc2 로 미리 한 번 돌려 보라는 것이 Go 팀의 공식 권고입니다. 정식이 나오면 이 페이지의 수치가 달라질 일은 거의 없을 테니, 저는 여기까지만 하겠습니다.