Menu
CoddyTech

제네릭 소개

Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 67번째.

Go 1.18 이전에는 여러 타입에 사용할 수 있는 재사용 가능한 코드를 작성하려면 함수를 복제하거나 타입 단언과 함께 빈 인터페이스 any를 사용해야 했습니다. 제네릭을 사용하면 완전한 타입 안전성을 유지하면서 여러 타입에 작동하는 함수와 타입을 작성할 수 있으므로 이 문제를 해결할 수 있습니다.

슬라이스에서 최솟값을 찾는다고 생각해 보세요. 제네릭이 없다면 각 타입마다 별도의 함수가 필요합니다.

func MinInt(values []int) int {
    min := values[0]
    for _, v := range values {
        if v < min {
            min = v
        }
    }
    return min
}

func MinFloat64(values []float64) float64 {
    min := values[0]
    for _, v := range values {
        if v < min {
            min = v
        }
    }
    return min
}

제네릭을 사용하면 대괄호 안에 타입 매개변수를 넣어 로직을 한 번만 작성할 수 있습니다.

func Min[T int | float64](values []T) T {
    min := values[0]
    for _, v := range values {
        if v < min {
            min = v
        }
    }
    return min
}

[T int | float64]는 int 또는 float64가 될 수 있는 타입 매개변수 T를 선언합니다. 이제 같은 함수로 Min([]int{3, 1, 2}) 또는 Min([]float64{3.5, 1.2})를 호출할 수 있습니다. 컴파일러가 컴파일 시점에 타입을 검사하므로 런타임 오버헤드 없이 안전성을 확보할 수 있습니다.

앞으로의 수업에서는 타입 매개변수, 제약 조건, 제네릭 구조체를 자세히 살펴보겠습니다.

challenge icon

챌린지

쉬움

제네릭을 사용해 정수 점수와 부동 소수점 점수 모두를 처리하는 점수 분석기를 만들어 봅시다! 슬라이스에서 최댓값을 찾을 수 있는 제네릭 함수 하나를 만들어 숫자 유형마다 코드를 중복해서 작성할 필요가 없도록 합니다.

코드를 두 파일에 나누어 작성합니다.

  • analyzer.go: 제네릭 분석 함수를 정의합니다.

    슬라이스에서 최댓값을 찾아 반환하는 제네릭 함수 Max[T int | float64](values []T) T를 만듭니다. 이 함수는 타입 매개변수 T를 통해 int와 float64 유형 모두에서 작동해야 합니다.

    또한 슬라이스의 모든 값의 합을 계산해 반환하는 제네릭 함수 Sum[T int | float64](values []T) T도 만듭니다.

  • main.go: 입력을 읽고 서로 다른 유형으로 제네릭 함수를 실행해 봅니다.

    유형 표시자(int 또는 float)를 읽은 다음, 개수를 읽고 그 개수만큼 값을 읽습니다. 유형에 따라 값을 파싱하고, 적절한 유형으로 Max와 Sum을 모두 호출한 후 결과를 출력합니다.

    정수 입력의 경우 다음을 출력합니다.

    Max (int): [value]
    Sum (int): [value]

    부동 소수점 입력의 경우 소수점 이하 한 자리까지 출력합니다.

    Max (float): [value]
    Sum (float): [value]

다음 입력이 제공됩니다.

  • 1번째 줄: 유형 표시자(int 또는 float)
  • 2번째 줄: 값의 개수(정수)
  • 그다음 줄들: 줄마다 값 하나

예를 들어, 다음이 주어지면:

int
4
15
8
23
11

다음과 같이 출력해야 합니다.

Max (int): 23
Sum (int): 57

그리고 다음이 주어지면:

float
3
4.5
9.2
6.8

다음과 같이 출력해야 합니다.

Max (float): 9.2
Sum (float): 20.5

같은 제네릭 함수가 정수 데이터와 부동 소수점 데이터 모두를 처리하는 방식을 살펴보세요. 타입 매개변수 [T int | float64]를 사용하면 로직은 한 번만 작성하면서 컴파일러가 각 사용 사례에 맞는 타입 안전 코드를 생성할 수 있습니다.

직접 해보기

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// 타입 표시자를 읽기
	typeStr, _ := reader.ReadString('\n')
	typeStr = strings.TrimSpace(typeStr)

	// 개수를 읽기
	countStr, _ := reader.ReadString('\n')
	count, _ := strconv.Atoi(strings.TrimSpace(countStr))

	if typeStr == "int" {
		// 정수 값을 읽기
		values := make([]int, count)
		for i := 0; i < count; i++ {
			line, _ := reader.ReadString('\n')
			values[i], _ = strconv.Atoi(strings.TrimSpace(line))
		}

		// TODO: 정수 슬라이스로 Max와 Sum 호출하기
		// TODO: 결과를 "Max (int): [value]"와 "Sum (int): [value]" 형식으로 출력하기

	} else if typeStr == "float" {
		// 실수 값을 읽기
		values := make([]float64, count)
		for i := 0; i < count; i++ {
			line, _ := reader.ReadString('\n')
			values[i], _ = strconv.ParseFloat(strings.TrimSpace(line), 64)
		}

		// TODO: float64 슬라이스로 Max와 Sum 호출하기
		// TODO: 결과를 소수점 첫째 자리까지 "Max (float): [value]"와 "Sum (float): [value]" 형식으로 출력하기
	}
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Go 컴파일러