Golangで探る!ジェネリクス活用の実践テクニック

はじめに

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におけるジェネリクスの導入は、開発者にとって大きなメリットをもたらしています。この記事を通じて、ジェネリクスの基本的な使い方とその強力な機能を理解し、あなたのコードに活かしていただければ幸いです。

タイトルとURLをコピーしました