Go言語のジェネリクスとは?
Go言語のジェネリクスは、コードを再利用しやすく、安全かつ効率的にプログラミングするためのメカニズムです。
具体的には、同じ構造を持つ複数の型を扱う関数や構造体を、一つのジェネリックな関数や構造体に定義することで、各型に対して同じ処理を行うコードを再利用できます。
以下の構文で使用できます。
func 関数名(t Type) { ... }
具体的なコード例1
例えば、以下のようなジェネリックな関数を定義します。
func Swap(a, b *T) {
temp := *a
*a = *b
*b = temp
}
この関数は、任意の型のポインターを受け取り、それらのポインターが指す変数を交換する関数です。
この関数を使って、int型、float64型、文字列型の変数を交換することができます。
x := 1
y := 2
Swap(&x, &y)
fmt.Println(x, y) // 2 1
x := 3.14
y := 2.718
Swap(&x, &y)
fmt.Println(x, y) // 2.718 3.14
x := "hello"
y := "world"
Swap(&x, &y)
fmt.Println(x, y) // world hello
このように、ジェネリックな関数を使うことで、同じ処理を行うコードを再利用することができ、プログラミングを効率的にすることができます。
具体的なコード例2
他にも、ジェネリックなアルゴリズムやデータ構造を定義することができます。
例えば、以下のようなジェネリックな関数を定義します。
func Max(a, b T) T {
if a > b {
return a
}
return b
}
この関数は、任意の型の値を受け取り、それらの中で最大の値を返す関数です。この関数を使って、int型、float64型、文字列型の変数の最大値を取得することができます。
x := Max(1, 2)
fmt.Println(x) // 2
x := Max(3.14, 2.718)
fmt.Println(x) // 3.14
x := Max("hello", "world")
fmt.Println(x) // world
構造体を使った例
ジェネリックな構造体も使うことができます。
例えば、以下のようなジェネリックな構造体を定義します。
type Pair struct {
first, second T
}
この構造体は、任意の型の値を保持することができ、firstとsecondというフィールドに保持します。この構造体を使って、int型、float64型、文字列型のペアを作成することができます。
p := Pair{first: 1, second: 2}
fmt.Println(p.first, p.second) // 1 2
p := Pair{first: 3.14, second: 2.718}
fmt.Println(p.first, p.second) // 3.14 2.718
p := Pair{first: "hello", second: "world"}
fmt.Println(p.first, p.second) // hello world
また、ジェネリックな構造体には、任意の型を扱うためのメソッドを定義することもできます。
例えば、以下のようなジェネリックな構造体に、インターフェイスを実装したメソッドを定義することができます。
type Pair struct {
first, second T
}
func (p Pair) String() string {
return fmt.Sprintf("first: %v, second: %v", p.first, p.second)
}
このように、ジェネリックな構造体を使うことで、同じ構造を持つ複数の型を扱うことができ、プログラミングを効率的にすることができます。