まとめ:ジェネリックコレクション
CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 72/107。
チャレンジ
簡単Goのジェネリクスについて学んだことのすべてを実証する、汎用的な Queue(キュー)データ構造を構築しましょう!スタック(LIFO)とは異なり、キューは先入れ先出し(FIFO)の順序に従います。つまり、最初に追加されたアイテムが最初に削除されます。
コードは2つのファイルに分けて構成します:
queue.go: 汎用的なキューコレクションを定義します。内部にアイテムを格納するジェネリックな構造体
Queue[T any]を作成します。キューは以下の操作をサポートする必要があります:Enqueue(item T)- キューの最後尾にアイテムを追加しますDequeue() (T, bool)- キューの先頭からアイテムを削除して返し、成功を示すブール値を併せて返します(キューが空の場合はゼロ値とfalseを返します)Peek() (T, bool)- アイテムを削除せずに先頭のアイテムを返します(Dequeueと同じ戻り値のパターンです)Size() int- キュー内のアイテム数を返しますIsEmpty() bool- キューにアイテムがない場合に true を返します
また、初期化された空のキューへのポインタを返すコンストラクタ関数
NewQueue[T any]() *Queue[T]も作成してください。main.go: 入力に基づいて、異なる型でキューを実証します。型インジケータ(
intまたはstring)を読み取り、次にキューに対して実行する一連のコマンドを読み取ります。各コマンドはそれぞれの行に記述されます:enqueue [value]- キューに値を追加しますdequeue- 先頭のアイテムを削除して出力します(キューが空の場合はemptyを出力します)peek- 削除せずに先頭のアイテムを出力します(キューが空の場合はemptyを出力します)size- 現在のサイズを出力します
doneを受け取るまでコマンドを読み取ります。
以下の入力が提供されます:
- 1行目:型インジケータ(
intまたはstring) - 以降の行:
doneまでのコマンド
例えば、以下のように与えられた場合:
int
enqueue 10
enqueue 20
enqueue 30
peek
dequeue
size
dequeue
dequeue
dequeue
done出力は以下のようになります:
10
10
2
20
30
emptyまた、以下のように与えられた場合:
string
enqueue hello
enqueue world
size
peek
dequeue
peek
done出力は以下のようになります:
2
hello
hello
world作成したキューは、整数型と文字列型の両方で同様に動作し、単一のジェネリックな実装が完全な型安全性を維持しながら、複数の具体的な型をどのように処理するかを示す必要があります。
自分で試してみよう
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// 型インジケーターを読み取る
scanner.Scan()
typeIndicator := scanner.Text()
if typeIndicator == "int" {
// TODO: NewQueue[int]() を使用して整数キューを作成する
// 整数キューのコマンドを処理する
for scanner.Scan() {
line := scanner.Text()
if line == "done" {
break
}
parts := strings.SplitN(line, " ", 2)
command := parts[0]
// TODO: コマンドを処理する: enqueue, dequeue, peek, size
// enqueue の場合、parts[1] から整数値を解析する
// dequeue/peek の場合、キューが空なら "empty" を出力する
_ = command
}
} else if typeIndicator == "string" {
// TODO: NewQueue[string]() を使用して文字列キューを作成する
// 文字列キューのコマンドを処理する
for scanner.Scan() {
line := scanner.Text()
if line == "done" {
break
}
parts := strings.SplitN(line, " ", 2)
command := parts[0]
// TODO: コマンドを処理する: enqueue, dequeue, peek, size
// enqueue の場合、parts[1] の文字列値を使用する
// dequeue/peek の場合、キューが空なら "empty" を出力する
_ = command
}
}
// これらは開発中の未使用のインポートエラーを避けるために記述されています
_ = strconv.Atoi
_ = fmt.Println
}
オブジェクト指向プログラミングのすべてのレッスン
1Go オブジェクト指向の基礎
外部ファイルGo ワークスペースとモジュールパッケージとインポート公開された名前と非公開の名前Go におけるオブジェクト指向入門クラスとしての構造体構造体へのメソッド定義ポインタレシーバと値レシーバ構造体の初期化コンストラクタ関数まとめ:簡易計算機8エラー処理とOOP
error インターフェースカスタムエラー型エラーラッピング (fmt.Errorf)センチネルエラーerrors.Is() と errors.As()Panic、Defer、Recover復習 - ファイルパーサー