结构体字段必须首字母大写才能被 json 序列化和 sort.slice 访问;推荐用 sort.slice 实现单级或多级排序,避免手动实现 sort.interface。

结构体定义要带可导出字段,否则 JSON 和排序会失效
Go 的 struct 字段首字母小写就是私有字段,json.Marshal 会忽略它们,sort.Slice 里访问不到,排序结果为空或 panic。必须确保 Name、Score、ID 这类字段首字母大写。
- 错误写法:
type Student struct { name string; score float64 }→ 序列化后是{} - 正确写法:
type Student struct { Name string; Score float64; ID int } - 如果真需要内部存储小写字段,可用 tag 显式绑定:
Name string `json:"name"`,但排序逻辑仍依赖字段名可访问
用 sort.Slice 按 Score 降序排,别碰 sort.Sort + Interface
对结构体切片排序,sort.Slice 是最直接的选择;硬写 sort.Interface 实现不仅冗长,还容易在 Less 函数里漏掉边界判断(比如 nil 切片),导致 panic。
- 升序:
sort.Slice(students, func(i, j int) bool { return students[i].Score - 降序(更常用):
sort.Slice(students, func(i, j int) bool { return students[i].Score > students[j].Score }) - 多级排序(先按 Score 降序,相同则按 Name 字典升序):
return s[i].Score > s[j].Score || (s[i].Score == s[j].Score && s[i].Name
从文件读取成绩数据时,JSON 解析失败常因字段类型不匹配
比如 JSON 文件里 "score": "89.5"(字符串)但 struct 定义为 Score float64,json.Unmarshal 会静默失败(返回 nil error 但字段值为 0),查不出错在哪。
- 检查原始 JSON:用
cat data.json | jq '.'确认字段类型是否一致 - 临时加校验:
if len(students) == 0 { log.Fatal("no students parsed — check JSON format and field casing") } - 更稳妥的兼容写法:定义自定义类型并实现
UnmarshalJSON,但简易系统里建议统一用数字写 JSON,避免字符串混入
查找学生时用 map 做 ID 索引比遍历切片快得多
每次查 ID == 1001 都用 for range 遍历切片,O(n) 复杂度;1000 个学生查 10 次就是上万次比较。而初始化一次 map[int]Student 后,查就是 O(1)。
立即学习“go语言免费学习笔记(深入)”;
- 构建索引:
idMap := make(map[int]Student); for _, s := range students { idMap[s.ID] = s } - 查找:
if s, ok := idMap[1001]; ok { ... } - 注意:ID 重复时后读入的会覆盖前一个 —— 如果业务允许重复 ID,就不能用 map,得回退到遍历 + 条件过滤
Less 写错了,结果发现是 JSON 根本没解析出来。先打一行 fmt.Printf("loaded %d students\n", len(students)),比瞎猜快得多。










