PHpullh
학습 라이브러리/Go/제네릭 (Go 1.18+)

GO · 구조체/인터페이스

제네릭 (Go 1.18+)

Go 1.18에 추가된 제네릭으로 타입 안전한 재사용 가능한 코드를 작성합니다.

구조체/인터페이스중급generic제네릭constraintsTypeParamGo 1.18

핵심 설명

Go 1.18에 추가된 제네릭으로 타입 안전한 재사용 가능한 코드를 작성합니다.

Go code

package main

import (
	"fmt"
	"golang.org/x/exp/constraints"
)

// 타입 파라미터 — [T constraint]
func Map[T, U any](s []T, fn func(T) U) []U {
	result := make([]U, len(s))
	for i, v := range s { result[i] = fn(v) }
	return result
}

func Filter[T any](s []T, fn func(T) bool) []T {
	var result []T
	for _, v := range s {
		if fn(v) { result = append(result, v) }
	}
	return result
}

// constraints.Ordered — 정렬 가능한 타입 제약
func Min[T constraints.Ordered](a, b T) T {
	if a < b { return a }
	return b
}

// 제네릭 구조체
type Stack[T any] struct {
	data []T
}

func (s *Stack[T]) Push(v T)     { s.data = append(s.data, v) }
func (s *Stack[T]) Pop() (T, bool) {
	if len(s.data) == 0 {
		var zero T
		return zero, false
	}
	n := len(s.data) - 1
	v := s.data[n]
	s.data = s.data[:n]
	return v, true
}
func (s *Stack[T]) Len() int { return len(s.data) }

// 커스텀 타입 제약
type Number interface {
	~int | ~int32 | ~int64 | ~float32 | ~float64
}

func Sum[T Number](nums []T) T {
	var total T
	for _, n := range nums { total += n }
	return total
}

func main() {
	nums := []int{1, 2, 3, 4, 5}
	doubled := Map(nums, func(n int) int { return n * 2 })
	fmt.Println(doubled) // [2 4 6 8 10]

	strs := Map(nums, func(n int) string {
		return fmt.Sprintf("item%d", n)
	})
	fmt.Println(strs)

	evens := Filter(nums, func(n int) bool { return n%2 == 0 })
	fmt.Println(evens) // [2 4]

	fmt.Println(Min(3, 5))       // 3
	fmt.Println(Min("a", "b"))   // a

	var s Stack[string]
	s.Push("hello"); s.Push("world")
	if v, ok := s.Pop(); ok { fmt.Println(v) } // world

	fmt.Println(Sum([]float64{1.1, 2.2, 3.3}))
}

학습 팁

제네릭은 실제로 필요할 때만 사용하세요. Go의 철학은 "단순함"입니다. 인터페이스로 해결되면 제네릭을 피하는 것이 관례입니다.

주의할 점

constraints 패키지는 golang.org/x/exp에 있습니다. Go 1.21+에서는 cmp 패키지로 일부가 표준화됐습니다.

자주 묻는 질문

제네릭 (Go 1.18+)란 무엇인가요?

Go 1.18에 추가된 제네릭으로 타입 안전한 재사용 가능한 코드를 작성합니다.

제네릭 (Go 1.18+) 학습 시 주의할 점은 무엇인가요?

constraints 패키지는 golang.org/x/exp 에 있습니다. Go 1.21+에서는 cmp 패키지로 일부가 표준화됐습니다.