[GO] Tucker의 GO 언어 프로그래밍 - 24장 제네릭 프로그래밍
ㅁ 들어가며
ㅇ Tucker의 GO 언어 프로그래밍 책을 보고 정리한 글입니다.
ㅇ [GO] Tucker의 GO 언어 프로그래밍 - 목차
ㅁ 제네릭 프로그래밍 소개
제네릭 프로그래밍은 Go 1.18 버전에서 도입된 기능으로, 타입에 구애받지 않고 재사용 가능한 코드를 작성할 수 있게 해준다. 이를 통해 개발자는 다양한 데이터 타입에 대해 동작하는 함수와 데이터 구조를 만들 수 있으며, 코드 중복을 줄이고 타입 안정성을 높일 수 있다.
ㅁ 제네릭 함수
ㅇ 제네릭 함수는 타입 매개변수를 사용하여 여러 타입에 대해 동작할 수 있는 함수이다.
func Max[T comparable](a, b T) T {
if a > b {
return a
}
return b
}
ㅇ 이 함수는 comparable제약 조건을 만족하는 모든 타입 T에 대해 사용할 수 있다.
ㅁ 제네릭 타입
ㅇ 제네릭 타입을 사용하면 다양한 타입에 대해 동작하는 데이터 구조를 정의할 수 있다.
type Stack[T any] struct {
elements []T
}
func (s *Stack[T]) Push(element T) {
s.elements = append(s.elements, element)
}
func (s *Stack[T]) Pop() T {
element := s.elements[len(s.elements)-1]
s.elements = s.elements[:len(s.elements)-1]
return element
}
ㅇ 이 스택 구현은 어떤 타입의 요소든 저장할 수 있다.
ㅁ 언제 제네릭 프로그래밍을 사용해야 하는가?
ㅇ 제네릭 프로그래밍은 공통적으로 사용되는 자료구조에 유용하다.
- 재사용 가능한 데이터 구조 구현 (예: 연결 리스트, 이진 트리, 힙)
- 슬라이스, 맵, 채널 등 다양한 타입에 대해 작동하는 함수 작성
- 타입 안정성을 유지하면서 코드 중복을 줄이고자 할 때
- 알고리즘을 구현할 때 (예: 정렬, 검색, 필터링)
ㅇ 객체의 타입이 아닌 객체의 기능이 강조되는 곳에서는 인터페이스를 사용(p527)
ㅇ 성능(p525)
- 제네릭 함수나 타입의 경우 하나의 함수나 타입처럼 보이지만 실제로는 컴파일 타임에 사용한 타입 파라미터별로 새로운 함수나 타입을 생성해서 사용하게 된다.
- 제네릭 프로그래밍을 많이 사용하면 컴파일 시 함수와 타입 개수가 늘어 컴파일 지연이 발생되고 용량 제한이 있는 임베디드 환경에서는 문제가 될 수 있다.
ㅁ 제네릭을 사용해 만든 유용한 기본 패키지
Go 1.18 이후 버전에서는 제네릭을 활용한 여러 유용한 패키지가 등장했다.
golang.org/x/exp/slices
: 슬라이스 조작을 위한 제네릭 함수들을 제공한다.(p528)golang.org/x/exp/maps
: 맵 조작을 위한 제네릭 함수들을 제공한다.(p532)
ㅁ 인터페이스와 제네릭 비교
[GO] 인터페이스와 제네릭의 차이점은?에 정리함.
ㅁ 마무리
제네릭 프로그래밍은 여러 타입에 대해서 동작할 수 있도록 하여 중복 코드를 줄일 수 있다.
인터페이스는 다형성을 구현하고 객체의 행동을 정의하고, 제네릭은 타입에 구애받지 않는 재사용 가능한 코드를 작성한다.
제네릭 프로그래밍은 Go 언어에 큰 유연성을 더해주었지만, 사용 시 성능 영향을 고려해야 하며 필요한 경우에만 적절히 사용하는 것이 중요하다.