はじめに
Golangがついにジェネリクスを導入し、プログラミングの世界に新しい風を吹き込んでいます。
この記事では、Golangのジェネリクスがもたらす便利さとその具体的な使い方を、実践的なコード例を交えて解説していきます。
ジェネリクスとは何か?
Golangではバージョン1.18から、待望のジェネリクス機能が導入されました。ジェネリクスとは、型をパラメータ化して、より汎用的で再利用可能なコードを実現するための機能です。
ジェネリクスの基本的な使い方
コード例1: マップのリデュース関数
package main
import "fmt"
func Reduce[T any](s []T, init T, f func(T, T) T) T {
acc := init
for _, v := range s {
acc = f(acc, v)
}
return acc
}
func main() {
ints := []int{1, 2, 3, 4, 5}
sum := Reduce(ints, 0, func(a, b int) int { return a + b })
fmt.Println("Sum:", sum)
}
このコードでは、任意の型 T
のスライスを受け取り、それを統合して単一の値にまとめるリデュース関数を実装しています。
コード例2: 汎用的なスタック構造
package main
import "fmt"
type Stack[T any] struct {
elements []T
}
func (s *Stack[T]) Push(v T) {
s.elements = append(s.elements, v)
}
func (s *Stack[T]) Pop() T {
if len(s.elements) == 0 {
panic("stack is empty")
}
v := s.elements[len(s.elements)-1]
s.elements = s.elements[:len(s.elements)-1]
return v
}
func main() {
stack := Stack[int]{}
stack.Push(42)
stack.Push(23)
fmt.Println("Pop:", stack.Pop())
fmt.Println("Pop:", stack.Pop())
}
こちらの例では、任意の型 T
に対応する汎用的なスタック構造を実装しています。
ジェネリクスを使うメリット
ジェネリクスを利用することで、コードの再利用性と可読性が向上します。また、型安全性を保ちつつ、様々なデータ型に対応した関数やデータ構造を柔軟に設計することが可能になります。
まとめ
Golangにおけるジェネリクスの導入は、開発者にとって大きなメリットをもたらしています。この記事を通じて、ジェネリクスの基本的な使い方とその強力な機能を理解し、あなたのコードに活かしていただければ幸いです。