Menu
Coddy logo textTech

まとめ:ジェネリックコレクション

CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 72/107。

challenge icon

チャレンジ

簡単

Go のジェネリクスについて学んだことをすべて示す、汎用的な Queue データ構造を作ってみましょう!スタック(LIFO)とは異なり、queue は First-In-First-Out(FIFO)の順序に従います。つまり、最初に追加された item が最初に削除されます。

コードを 2 つのファイルに分けて整理します。

  • queue.go: ジェネリックな queue コレクションを Define します。

    item を internally に格納するジェネリックな構造体 Queue[T any] を作成します。queue は次の操作をサポートする必要があります。

    • Enqueue(item T) - queue の back に item を adds します
    • Dequeue() (T, bool) - queue の front から item を削除して返し、成功したかどうかを示す bool も返します(queue が空の場合は zero value と false を返します)
    • Peek() (T, bool) - front の item を削除せずに返します(Dequeue と同じ戻り値のパターンです)
    • Size() int - queue 内の item の number を返します
    • IsEmpty() bool - queue に item がない場合に true を返します

    また、初期化された空の queue への pointer を返す constructor function NewQueue[T any]() *Queue[T] も作成します。

  • main.go: 入力に基づいて異なる型で queue を実演します。

    型の indicator(int または string)を読み取り、その後 queue に対して実行する一連の commands を読み取ります。各 command はそれぞれ独自の line に記述されます。

    • enqueue [value] - value を queue に追加します
    • dequeue - front の item を削除して print します(queue が空の場合は empty を print します)
    • peek - front の item を削除せずに print します(queue が空の場合は empty を print します)
    • size - 現在の size を print します

    done を受け取るまで commands を読み取ります。

次の入力が提供されます。

  • Line 1: 型の indicator(int または string
  • Following lines: done までの commands

たとえば、次の入力が与えられた場合:

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

この queue は integer 型と string 型の両方で同じように動作する必要があります。これにより、単一のジェネリック実装で複数の具体的な型を扱いながら、完全な型安全性を維持できることを示します。

自分で試してみよう

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
}

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Goオンラインコンパイラ