Goのジェネリクスがよく理解できていなかったので、調べてみました。
ジェネリクス導入前
int型、float64型のそれぞれで同じ処理をする関数を定義しています。
型が異なるので、両者を一緒に計算したり、戻り値で返したりすることができません。
package main
import "fmt"
// intスライスの合計を計算する関数
func sumIntSlice(slice []int) int {
sum := 0
for _, v := range slice {
sum += v
}
return sum
}
// float64スライスの合計を計算する関数
func sumFloat64Slice(slice []float64) float64 {
sum := 0.0
for _, v := range slice {
sum += v
}
return sum
}
func main() {
intSlice := []int{1, 2, 3, 4, 5}
floatSlice := []float64{1.1, 2.2, 3.3, 4.4, 5.5}
fmt.Println("Sum of int slice:", sumIntSlice(intSlice))
fmt.Println("Sum of float64 slice:", sumFloat64Slice(floatSlice))
}
ジェネリクス導入後
Addable型を定義して、それをsumSlice関数のジェネリクスとして指定しています。
引数もAddable型のスライス、戻り値もAddable型とします。
こうすることで、int型・float64型どちらも1つの関数で処理することができ、コードの再利用性が向上します。
package main
import "fmt"
// 制約として、加算が可能な型を指定
type Addable interface {
int | float64
}
// ジェネリクスを使ったスライスの合計を計算する関数
func sumSlice[T Addable](slice []T) T {
var sum T
for _, v := range slice {
sum += v
}
return sum
}
func main() {
intSlice := []int{1, 2, 3, 4, 5}
floatSlice := []float64{1.1, 2.2, 3.3, 4.4, 5.5}
fmt.Println("Sum of int slice:", sumSlice(intSlice))
fmt.Println("Sum of float64 slice:", sumSlice(floatSlice))
}
動かしてみる
go run main.go
Sum of int slice: 15
Sum of float64 slice: 16.5