Go 1.21 베타 제네릭 개선점 정리

배경

Go 1.18에서 제네릭이 도입된 후 실무에 적용해보면서 몇 가지 불편함을 느꼈다. 특히 타입 추론이 예상보다 제한적이어서 명시적으로 타입 파라미터를 지정해야 하는 경우가 많았다.

1.21 베타가 나와서 변경사항을 확인해봤다.

주요 개선점

타입 추론 강화

기존 1.20에서는 이런 코드가 컴파일되지 않았다:

func Map[T, U any](slice []T, fn func(T) U) []U {
    result := make([]U, len(slice))
    for i, v := range slice {
        result[i] = fn(v)
    }
    return result
}

// 1.20: 타입 명시 필요
result := Map[int, string](numbers, strconv.Itoa)

1.21부터는 함수 인자로부터 타입을 추론한다:

// 1.21: 타입 추론 가능
result := Map(numbers, strconv.Itoa)

실무 적용 사례

사내 API 클라이언트 라이브러리를 리팩토링하면서 제네릭을 활용한 공통 응답 처리 함수를 만들었다:

type APIResponse[T any] struct {
    Data    T      `json:"data"`
    Error   string `json:"error,omitempty"`
    Success bool   `json:"success"`
}

func Fetch[T any](ctx context.Context, url string) (*APIResponse[T], error) {
    resp, err := http.Get(url)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    
    var result APIResponse[T]
    if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
        return nil, err
    }
    return &result, nil
}

1.20에서는 Fetch[UserData](ctx, url) 형태로 호출해야 했지만, 1.21부터는 반환 타입으로 추론이 가능해져서 코드가 깔끔해졌다.

성능

제네릭 코드의 컴파일 시간이 약 15% 단축되었다고 한다. 실제로 테스트해보니 체감할 정도는 아니었지만 긍정적인 변화다.

정리

1.21 정식 출시는 8월 예정이다. 타입 추론 개선만으로도 제네릭 사용성이 크게 향상될 것으로 보인다. 프로덕션 적용은 좀 더 지켜본 후 결정할 예정이다.