图书结构体需导出字段(首字母大写),isbn用string,title/author设默认值或校验;切片操作须接收append返回值,查找用range获取索引,删除用append(...)...复用底层数组。

用结构体定义图书数据模型,别漏掉可比较字段
Go 中结构体是描述图书最自然的方式,但容易忽略字段的可导出性(首字母大写)和实际使用场景。比如搜索、排序、持久化都依赖字段可访问;ISBN 建议用 string 而非 int64,因为含短横线或前导零;Title 和 Author 不能为空字符串,初始化时建议设默认值或加校验。
-
type Book struct { ID int; Title string; Author string; ISBN string; Year int }—— 所有字段必须导出才能被外部函数读写 - 避免用指针字段如
*string存书名,除非明确需要区分“空”和“未设置” - 如果后续要支持 JSON 序列化(比如存文件),字段需加 tag:
json:"title"
用切片管理多本图书,注意追加与查找的边界问题
切片是动态集合的首选,但新手常误以为 append 会原地修改底层数组——它可能分配新内存,所以必须接收返回值。另外,基于切片的查找(如按标题找书)没有内置方法,得手写循环,别直接套用 Python 的 in 逻辑。
- 声明:
var books []Book,不是books := []Book{}—— 后者虽等效,但前者更清晰表达“可能为空”的语义 - 添加一本新书必须写成:
books = append(books, newBook),漏掉赋值会导致数据丢失 - 查找某本书时,用
for i, b := range books,别用for _, b := range books然后想改b字段——那是副本,改了没用
控制台交互时,输入解析最容易崩在类型转换上
用户从终端输个年份,fmt.Scanln 拿到的是字符串,直接转 int 会 panic。错误信息通常是 strconv.Atoi: parsing "abc": invalid syntax,但程序直接退出,没提示重试。
- 用
fmt.Scanln(&input)后,先检查input是否为空或只含空白符,再尝试转换 - 年份、ID 这类数字字段,统一用
strconv.Atoi并检查 error,失败就打印提示并 continue 当前操作循环 - 别用
fmt.Scanf("%d", &year)读整数——用户多敲个空格或字母就会卡住,且不报错
删除图书时,切片“缩容”写法不对会留脏数据
删第 i 本书,常见错误是 books[i] = Book{} 或 books = books[:i] + books[i+1:]。前者只是清空值,长度不变;后者性能差(新建切片+拷贝),且在大量数据下易触发 GC 压力。
立即学习“go语言免费学习笔记(深入)”;
- 正确做法是:
books = append(books[:i], books[i+1:]...)—— 利用...展开尾部,复用底层数组 - 删除前务必确认索引
i ,否则 panic: <code>runtime error: index out of range - 如果删除后要继续遍历剩余元素,注意索引偏移:删掉第
i个后,原i+1变成新i,循环变量别自增两次










