回顾:泛型集合
本课属于 Coddy GO 学习旅程的“面向对象编程”单元。第 72 课,共 107 课。
挑战
简单让我们来构建一个通用的 Queue 数据结构,展示你在 Go 中学到的所有泛型知识!与栈(后进先出)不同,队列遵循先进先出(FIFO)的顺序:最先添加的项会最先移除。
你将把代码分成两个文件:
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
}
面向对象编程中的所有课
自己练习: Go 在线编译器