
generic이란
제네릭(Generic)이란, 특정 타입에 의존하지 않고 다양한 타입을 지원하는 프로그래밍 기법입니다. 즉, 같은 코드로 여러 타입을 처리할 수 있도록 해주는 기능입니다. 쉽게 말해서 “하나의 코드로 여러 타입을 다룰 수 있게 해주는 도구”입니다.
generic이 필요한 이유
일반적으로 함수나 구조체는 특정 타입에 종속됩니다. 예를 들어, 두 개의 숫자를 더하는 함수를 만든다고 하면 아래와 같습니다.
func AddInt(a, b int) int {
return a + b
}
func AddFloat(a, b float64) float64 {
return a + b
}
위처럼 int와 float64를 각각 처리하는 별도의 함수를 만들어야 합니다. 하지만 제네릭을 사용하면 아래와 같이 하나의 코드로 여러 타입을 지원할 수 있습니다.
package main
import "fmt"
// 제네릭을 사용한 함수
// T는 타입 매개변수로, int 또는 float64 타입을 가질 수 있습니다.
func Add[T int | float64](a, b T) T {
return a + b
}
func main() {
fmt.Println(Add(3, 5)) // int 타입
fmt.Println(Add(3.2, 5.8)) // float64 타입
}
generic 핵심 개념
타입 매개변수 (Type Parameter)
제네릭에서는 타입을 변수처럼 사용합니다.
T, K, V 같은 이름을 사용하여 타입을 일반화할 수 있습니다.
func Add[T any](a, b T) T
타입 제약 (Type Constraint)
특정 타입만 허용하도록 제한할 수 있습니다.
func Add[T int | float64](a, b T) T: 숫자 타입만 허용
장점
코드 재사용성 증가: 같은 로직을 여러 타입에서 사용할 수 있어 중복 코드가 줄어듭니다.
단점
복잡성 증가: 코드가 복잡해질 수 있습니다.
런타임 성능 차이: 컴파일 시 타입별로 코드가 생성되므로, 경우에 따라 성능 영향을 받을 수 있습니다.
Golang에서의 generic
generic function
// generic을 사용하지 않은 경우
func AddInt(a, b int) int {
return a + b
}
func AddFloat(a, b float64) float64 {
return a + b
}
// generic을 사용한 경우
func Add[T int | float64](a, b T) T {
return a + b
}
func main() {
fmt.Println(Add(3, 5)) // int 타입
fmt.Println(Add(3.2, 5.8)) // float64 타입
}
generic struct
package main
import "fmt"
// 제네릭을 지원하는 구조체
type Box[T any] struct {
value T
}
func main() {
intBox := Box[int]{value: 10}
stringBox := Box[string]{value: "Hello"}
fmt.Println(intBox.value) // 10
fmt.Println(stringBox.value) // Hello
}
generic interface
package main
import "fmt"
// 제네릭 인터페이스
type Printer[T any] interface {
Print(T)
}
// 구조체가 인터페이스를 구현
type ConsolePrinter[T any] struct{}
func (cp ConsolePrinter[T]) Print(value T) {
fmt.Println(value)
}
func main() {
intPrinter := ConsolePrinter[int]{}
intPrinter.Print(42)
stringPrinter := ConsolePrinter[string]{}
stringPrinter.Print("Hello, Go!")
}
type constraints
Go에서는 제네릭 타입을 사용할 때 constraints를 정의하여 특정 타입만 허용할 수 있습니다.
package main
import (
"fmt"
"golang.org/x/exp/constraints"
)
// 숫자 타입만 허용하는 제네릭 함수
func Add[T constraints.Ordered](a, b T) T {
// int, float, string 등 비교 연산이 가능한 타입만 허용하는 제약조건
return a + b
}
func main() {
fmt.Println(Add(10, 20)) // int
fmt.Println(Add(3.5, 2.2)) // float64
}Go 제네릭 : NHN Cloud Meetup
Go 제네릭
https://meetup.nhncloud.com/posts/320
Go by Example: Generics
https://gobyexample.com/generics