개요
go 1.18에서 추가 된 제네릭의 사용 예
1. 함수에서의 사용
package main
import "fmt"
func Filter[T any](list []T, predicate func(T) bool) []T {
var result []T
for _, v := range list {
if predicate(v) {
result = append(result, v)
}
}
return result
}
func main() {
// 짝수만 필터
nums := []int{1, 2, 3, 4, 5, 6}
evens := Filter(nums, func(n int) bool {
return n%2 == 0
})
fmt.Println(evens) // [2 4 6]
// 길이가 5가 넘는 문자열만 필터
strings := []string{"apple", "banana", "cherry", "date"}
filteredStrings := Filter(strings, func(s string) bool {
return len(s) > 5
})
fmt.Println(filteredStrings) // ["banana", "cherry"]
}
- T는 타입 매개변수
- any
2. 구조체에서의 사용
package main
import "fmt"
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 {
if len(s.elements) == 0 {
var zero T
return zero
}
element := s.elements[len(s.elements)-1]
s.elements = s.elements[:len(s.elements)-1]
return element
}
func main() {
intStack := Stack[int]{}
intStack.Push(1)
intStack.Push(2)
fmt.Println(intStack.Pop()) // 2
stringStack := Stack[string]{}
stringStack.Push("hello")
stringStack.Push("world")
fmt.Println(stringStack.Pop()) // world
}
package main
import "fmt"
type Pair[T any] struct {
first, second T
}
func (p Pair[T]) Swap() Pair[T] {
return Pair[T]{p.second, p.first}
}
func main() {
intPair := Pair[int]{1, 2}
fmt.Println(intPair.Swap()) // {2 1}
stringPair := Pair[string]{"hello", "world"}
fmt.Println(stringPair.Swap()) // {world hello}
}
3. 인터페이스를 통한 타입 제한
package main
import "fmt"
type Adder interface {
Add() int
}
// Calculator1 Add 함수만 가지는 구조체
type Calculator1 struct {
a int
b int
}
func (c Calculator1) Add() int {
return c.a + c.b
}
// Calculator2 Minus 함수만 가지는 구조체
type Calculator2 struct {
a int
b int
}
func (c Calculator2) Minus() int {
return c.a - c.b
}
func AddValues[T Adder](adder T) int {
return adder.Add()
}
func main() {
// Calculator 인스턴스를 생성
calc := Calculator1{2, 3}
// AddValues 함수를 호출하여 두 값의 합을 계산
result := AddValues(calc)
fmt.Println(result) // 5
// Calculator2 인스턴스를 생성
//calc2 := Calculator2{5, 3}
//result2 := AddValues(calc2) // T (type Calculator2) does not satisfy Adder (missing method Add) 에러 발생
//fmt.Println(result2)
}
- Calculator1 구조체는 Adder 인터페이스를 구현하므로 AddValues 함수에 전달 가능
- Calculator2 구조체는 Adder 인터페이스를 구현하지 않으므로 AddValues 함수에 전달 불가
package main
import "fmt"
type Number interface {
int | float64
}
func Average[T Number](values []T) T {
var sum T
for _, v := range values {
sum += v
}
return sum / T(len(values))
}
func main() {
fmt.Println(Average([]int{1, 2, 3, 4, 5})) // 3 (int)
fmt.Println(Average([]float64{1.1, 2.2, 3.3})) // 2.2 (float64)
//fmt.Println(Average([]string{"apple", "banana"})) // string does not satisfy Number (string missing in int | float64) 에러 발생
}
참고:
'[Go]' 카테고리의 다른 글
[Go] Benchmark 사용법 (How to Use Benchmarks) (0) | 2024.06.25 |
---|---|
[Go] 구조체를 여러가지 방법으로 깊은 복사 하는 방법 + 성능비교 (How to deep copy a struct in various ways + Performance comparison) (0) | 2024.06.25 |
[Go] 고랭에서의 예외처리 (exception handling in golang) (0) | 2024.06.22 |
[Go] import cycle not allowed - 해결 방안1: interface를 활용한 해결 방안 (1) | 2024.06.18 |
[Go] import cycle not allowed - 예제 (0) | 2024.06.18 |