创建集合
本课属于 Coddy GO 学习旅程的“逻辑与流程”单元。第 32 课,共 68 课。
现在你已经了解了 Go 的集合惯用法背后的概念,是时候动手创建你的第一个集合了。这个过程很简单,遵循的模式与你已经学过的映射相同。
要在 Go 中创建集合,你可以使用 map[T]struct{} 模式声明一个变量,其中 T 是你要存储的元素类型。下面介绍如何创建一个用于存储不重复颜色名称的集合:
colors := make(map[string]struct{})你也可以使用映射字面量语法,为集合设置一些初始值:
colors := map[string]struct{}{
"red": {},
"blue": {},
"green": {},
}注意,每个值都是一个空的结构体字面量 {}。这会创建 struct{} 的零值,它不占用内存空间,同时仍允许键存在于映射中。
这种方法的好处在于,它利用了 Go 现有的映射基础设施,同时提供了真正的集合语义:每个颜色名称只能出现一次,而且查找速度和普通映射一样快。
挑战
简单创建一个编程语言偏好跟踪器,演示如何使用 Go 集合惯用法来存储唯一项。本挑战展示了如何使用 map[string]struct{} 模式跟踪编程语言,同时避免重复。
你会收到两个输入:
- 一个表示要处理的语言数量的字符串(例如,
"6") - 一个包含以逗号分隔的编程语言的字符串(例如,
"Go,Python,JavaScript,Go,Java,Python,C++,JavaScript")
你的任务是:
- 使用 Go 惯用写法
map[string]struct{}创建一个集合,用来存储唯一的编程语言 - 通过按逗号拆分输入字符串,解析出各个语言名称
- 将每种语言添加到集合中,并使用空结构体字面量
{}作为值 - 打印每种遇到的语言,以显示处理结果:
- 如果该语言尚未出现在集合中:
"Added: [language]" - 如果该语言已存在于集合中:
"Already exists: [language]"
- 如果该语言尚未出现在集合中:
- 处理完所有语言后,显示摘要:
"Total languages processed: [total_count]""Unique languages: [unique_count]"
- 最后,列出集合中的所有唯一语言:
- 标题:
"Programming languages in set:" - 每种语言单独占一行:
"- [language]"
- 标题:
使用 strings 包拆分输入字符串,并使用 strconv 包将数量字符串转换为整数。要在添加语言前检查它是否已存在于集合中,请使用逗号 ok 惯用法:_, exists := languageSet[language]。本挑战展示了 Go 集合惯用法如何高效地跟踪唯一项,并防止数据中出现重复项。
亲手试试
package main
import (
"fmt"
"sort"
"strconv"
"strings"
)
func main() {
// 读取输入
var countStr string
var languagesStr string
fmt.Scanln(&countStr)
fmt.Scanln(&languagesStr)
// 将计数字符串转换为整数(本挑战不需要)
_, _ = strconv.Atoi(countStr)
// 按逗号拆分 languages 字符串
languages := strings.Split(languagesStr, ",")
// 使用 map[string]struct{} 惯用写法创建集合
languageSet := make(map[string]struct{})
// TODO: 在下方编写你的代码
// 处理每种语言,检查它是否已在集合中
// 使用 comma ok 惯用写法:_, exists := languageSet[language]
// 输出 "Added: [language]" 或 "Already exists: [language]"
// 使用空结构体字面量 {} 将语言添加到集合中
// 输出汇总信息
// 输出处理的语言总数和不重复的语言数量
// 输出集合中所有不重复的语言
fmt.Println("Programming languages in set:")
// 将 map 转换为切片并排序,确保输出顺序一致
// 按 "- [language]" 格式列出每种语言
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。
逻辑与流程中的所有课
自己练习: Go 在线编译器