• Feed
  • Explore
  • Ranking
/
/
    Go

    Go generic에 대하여

    Go generic
    GoDevOps
    A
    Antonio
    2025.03.10
    ·
    5 min read

    3863

    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 핵심 개념

    1. 타입 매개변수 (Type Parameter)

      • 제네릭에서는 타입을 변수처럼 사용합니다.

      • T, K, V 같은 이름을 사용하여 타입을 일반화할 수 있습니다.

      • func Add[T any](a, b T) T

    2. 타입 제약 (Type Constraint)

      • 특정 타입만 허용하도록 제한할 수 있습니다.

      • func Add[T int | float64](a, b T) T : 숫자 타입만 허용

    3. 장점

      • 코드 재사용성 증가: 같은 로직을 여러 타입에서 사용할 수 있어 중복 코드가 줄어듭니다.

    4. 단점

      • 복잡성 증가: 코드가 복잡해질 수 있습니다.

      • 런타임 성능 차이: 컴파일 시 타입별로 코드가 생성되므로, 경우에 따라 성능 영향을 받을 수 있습니다.

    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






    - 컬렉션 아티클