ジェネリック機能とは、汎用的なデータ型や関数を実現するための機能であり、型安全かつコンパイル時にエラーを検出することができます。
以下、簡単なサンプルコードです。
type Stack[T any] []T
func (s *Stack[T]) Push(v T) {
*s = append(*s, v)
}
func (s *Stack[T]) Pop() (T, error) {
if len(*s) == 0 {
return nil, errors.New("stack is empty")
}
v := (*s)[len(*s)-1]
*s = (*s)[:len(*s)-1]
return v, nil
}
このコードでは、Stack
構造体に型パラメータT
を指定し、Push
メソッドと Pop
メソッドを定義しています。
Push
メソッドは、スタックに要素を追加するための関数であり、Pop
メソッドは、スタックの一番上にある要素を取り出すための関数であることがわかります。
Stack[T] 型のスタック構造体を使って、整数型のスタックを作成する例
func main() {
// 整数型のスタックを作成
var s Stack[int]
// スタックに要素を追加
s.Push(1)
s.Push(2)
s.Push(3)
// スタックから要素を取り出し
for len(s) > 0 {
v, err := s.Pop()
if err != nil {
fmt.Println(err)
break
}
fmt.Println(v)
}
}
このコードでは、まず Stack[int]
型のスタックを作成し、Push
メソッドを使って要素を追加しています。
その後、Pop
メソッドを使ってスタックの一番上にある要素を取り出し、fmt.Println
を使って出力しています。
Pop
メソッドは、取り出す要素がなくなるまで繰り返し呼び出され、エラーが発生した場合はエラーメッセージを出力してループを抜けるようになっています。
Stack[T] 型のスタック構造体を使って、文字列型のスタックを作成する例
func main() {
// 文字列型のスタックを作成
var s Stack[string]
// スタックに要素を追加
s.Push("foo")
s.Push("bar")
s.Push("baz")
// スタックから要素を取り出し
for len(s) > 0 {
v, err := s.Pop()
if err != nil {
fmt.Println(err)
break
}
fmt.Println(v)
}
}
このコードは、整数型のスタックを作成する例とほとんど同じですが、Stack[string]
型のスタックを作成しています。
Push
メソッドを使って文字列型の要素を追加し、Pop
メソッドを使ってスタックの一番上にある要素を取り出しています。fmt.Println
を使って出力する際も、文字列型に合わせて出力しています。
Stack[T] 型のスタック構造体を使って、マップ型のスタックを作成する例
func main() {
// マップ型のスタックを作成
var s Stack[map[string]int]
// スタックに要素を追加
s.Push(map[string]int{"foo": 1, "bar": 2})
s.Push(map[string]int{"baz": 3, "qux": 4})
s.Push(map[string]int{"quux": 5, "corge": 6})
// スタックから要素を取り出し
for len(s) > 0 {
v, err := s.Pop()
if err != nil {
fmt.Println(err)
break
}
fmt.Println(v)
}
}
このコードは、マップ型の要素を持つスタックを作成しています。
Stack[map[string]int]
型のスタックを作成し、Push
メソッドを使ってマップ型の要素を追加しています。
各マップには、キーと値が文字列型と整数型のペアで格納されています。
Pop
メソッドを使ってスタックの一番上にある要素を取り出す際には、map[string]int
型で要素を受け取っています。fmt.Println
を使って出力する際も、マップ型に合わせて出力しています。
このように、ジェネリック機能を使って定義したスタック構造体は、任意のデータ型に対応することができます。マップ型の例でも、整数型や文字列型の例と同様にスタックを作成することができます。