泛型数据结构
构建泛型 Stack 和 Set
泛型数据结构 是 CoddyKit 上的免费 Go Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Go Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Go Academy 课程共包含 4 节课。
为什么需要泛型数据结构
在泛型出现之前,Go 开发者会使用 interface{} 切片(失去类型安全),或者为每种类型生成代码。泛型可以实现类型安全且可复用的容器。
泛型栈
使用泛型类型实现的类型安全栈:
type Stack[T any] struct{ items []T }
func (s *Stack[T]) Push(v T) { s.items = append(s.items, v) }
func (s *Stack[T]) Pop() (T, bool) {
if len(s.items)==0 { var z T; return z, false }
n := len(s.items)-1; v := s.items[n]; s.items = s.items[:n]; return v, true
}
func (s *Stack[T]) Len() int { return len(s.items) }泛型队列
由切片支持的 FIFO 队列:
type Queue[T any] struct{ items []T }
func (q *Queue[T]) Enqueue(v T) { q.items = append(q.items, v) }
func (q *Queue[T]) Dequeue() (T, bool) {
if len(q.items)==0 { var z T; return z, false }
v := q.items[0]; q.items = q.items[1:]; return v, true
}泛型集合
由映射支持的集合——键类型必须支持比较:
type Set[T comparable] struct{ m map[T]struct{} }
func NewSet[T comparable]() *Set[T] { return &Set[T]{m: make(map[T]struct{})} }
func (s *Set[T]) Add(v T) { s.m[v] = struct{}{} }
func (s *Set[T]) Has(v T) bool { _, ok := s.m[v]; return ok }
func (s *Set[T]) Delete(v T) { delete(s.m, v) }泛型 Map 辅助函数
对切片执行类型安全函数式 Map:
func Map[T, U any](s []T, f func(T) U) []U {
out := make([]U, len(s))
for i, v := range s { out[i] = f(v) }
return out
}泛型 Filter
返回一个新切片,其中只包含满足谓词的元素:
func Filter[T any](s []T, predicate func(T) bool) []T {
var out []T
for _, v := range s {
if predicate(v) { out = append(out, v) }
}
return out
}泛型 Reduce
将切片折叠为单个值:
func Reduce[T, U any](s []T, init U, f func(U, T) U) U {
acc := init
for _, v := range s { acc = f(acc, v) }
return acc
}OrderedMap
一种保留插入顺序的有序映射——适用于需要稳定键顺序的 JSON 序列化:
type OrderedMap[K comparable, V any] struct {
keys []K
vals map[K]V
}泛型链表
元素具备类型安全的双向链表:
type Node[T any] struct{ Val T; Next, Prev *Node[T] }
type List[T any] struct{ head, tail *Node[T]; len int }限制
泛型类型不能对 T 使用类型切换。泛型类型的方法不能引入新的类型参数。您不能针对特定的 T 专门化泛型类型(不支持模板特化)。
性能
Go 通过“GC 形状”实现泛型实例化——具有相同内存布局的类型共享一个实现。这避免了代码膨胀,同时保持了接近具体实现的性能。
何时不应使用泛型
对于接口已经足够简单的情况,或者只有一两种具体类型的情况,请避免使用泛型——增加的复杂度往往超过其收益。
快速检查
为什么泛型 Set 的类型参数需要 comparable 约束?
回顾:泛型数据结构
要点:
- 使用泛型可以实现类型安全的 Stack、Queue、Set
- 函数式辅助函数:对 []T 使用 Map、Filter、Reduce
- 使用 Set[T comparable] 实现由映射支持的集合
- 不支持方法级类型参数,也不支持模板特化
常见问题解答
「泛型数据结构」课时是免费的吗?
是的 — 「泛型数据结构」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Go Academy 课程的其余内容,请升级到 CoddyKit PRO。 Go Academy 课程共包含 4 节课。
「泛型数据结构」这节课中我会学到什么?
构建泛型 Stack 和 Set 你通过在浏览器中直接运行的动手代码来练习 Go Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Go Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Go Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「泛型数据结构」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Go Academy 课中编写并运行代码吗?
能。每节 Go Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。