🐕

【Go】Genericsのサンプル

2024/02/21に公開

概要

この記事では、GoのGenerics(ジェネリクス)の使い方を確認する目的で、Genericsのサンプルを書いていきます。

スライスのフィルター関数

異なる型のスライスに対して、フィルタリングを行う関数です。

func Filter[T any](s []T, fn func(T) bool) []T {
	var result []T

	for _, v := range s {
		if fn(v) {
			result = append(result, v)
		}
	}

	return result
}

この関数を利用例をつぎに示します。

func main() {
	intSlice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	even := Filter(intSlice, func(i int) bool {
		return i%2 == 0
	})

	fmt.Println(even) // [2 4 6 8 10]

	strSlice := []string{"Apple", "Banana", "Grape", "Orange", "Pineapple"}
	longWords := Filter(strSlice, func(s string) bool {
		return len(s) > 5
	})

	fmt.Println(longWords) // [Banana Orange Pineapple]
}

スライスの最大を取得する関数

大小を比較するため、 型パラメータにはconstraints.Orderedインタフェースを指定します。

func Max[T constraints.Ordered](s []T) T {
	max := s[0]

	for _, v := range s {
		if v > max {
			max = v
		}
	}

	return max
}

この関数を利用例をつぎに示します。

func main() {
	intSlice := []int{1, 2, 3, 4, 5, 99 , 6, 7, 8, 9, 10}
	intMax := Max(intSlice)
	fmt.Println(intMax) // 99

	strSlice := []string{"Apple", "Banana", "Strawberry", "Pineapple"}
	strMax := Max(strSlice)
	fmt.Println(strMax) // Strawberry
}

constraints.Orderedインタフェース

constraints.Orderedインタフェースはつぎのように定義されています。

type Ordered interface {
	Integer | Float | ~string
}

これにより、IntegerFloat~stringをconstraints.Orderedインタフェースとして扱うことができるようになっています。

Underlying Type

前項のOrderedインタフェースでは、stringの前に~(チルダ)が指定された~stringという記述がありました。
これはUnderlying typeと呼ばれるもので、sringを基底とした型に制限するということを意味します。

例えばつぎのMyStringはstringを基底とした型であるため、型パラメータにconstraints.Orderedインタフェースを指定されている場合でも使用できます。

type MyString = string

参考) Underlying type constraints
https://go.dev/blog/deconstructing-type-parameters

Discussion