Goのジェネリクスを試してみた

Go

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