go语言项目--实例化(图书管理)--001

📅 2026/7/3 4:17:12
go语言项目--实例化(图书管理)--001
案例1图书管理系统golang一、项目概述项目名称图书管理系统当前版本v1.0 - 图书管理系统golang业务功能交互式命令行录入图书信息保存到books.txt学习目标Go基础语法变量、常量、类型流程控制if/else、for循环、break函数定义与多返回值错误处理error接口文件操作os.Create、bufio.Writer字符串处理strings.TrimSpace、strconv.ParseFloat运行方式go run main.go二、完整代码文件路径case1/main.gogo复制下载// // 图书管理系统 v1.0 - 图书录入器 // 功能交互式命令行录入图书信息保存到 books.txt // 学习目标基础语法、流程控制、函数、错误处理、文件操作 // 运行方式go run main.go // package main import ( bufio fmt os strconv strings ) // // 常量定义 // const ( dataFile books.txt // 数据文件名 exitCmd quit // 退出命令 ) // // 主函数 - 程序入口 // func main() { printWelcome() // 打开文件追加模式 file, err : os.OpenFile(dataFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err ! nil { fmt.Printf(❌ 打开文件失败: %v\n, err) return } defer file.Close() writer : bufio.NewWriter(file) defer writer.Flush() scanner : bufio.NewScanner(os.Stdin) count : 0 // 主循环 for { fmt.Print(\n 请输入书名,作者,价格输入 quit 退出: ) scanner.Scan() input : strings.TrimSpace(scanner.Text()) if input exitCmd { fmt.Printf(\n✅ 共录入 %d 本图书已保存到 %s\n, count, dataFile) break } // 解析输入 title, author, priceStr, err : parseInput(input) if err ! nil { fmt.Printf(❌ 格式错误: %v正确格式书名,作者,价格\n, err) continue } // 校验 if err : validateTitle(title); err ! nil { fmt.Printf(❌ %v\n, err) continue } if err : validateAuthor(author); err ! nil { fmt.Printf(❌ %v\n, err) continue } price, err : parsePrice(priceStr) if err ! nil { fmt.Printf(❌ %v\n, err) continue } // 写入文件 line : fmt.Sprintf(%s,%s,%.2f\n, title, author, price) if _, err : writer.WriteString(line); err ! nil { fmt.Printf(❌ 写入失败: %v\n, err) continue } writer.Flush() count fmt.Printf(✅ 第 %d 本录入成功: %s\n, count, strings.TrimSpace(line)) } } // // 辅助函数 // func printWelcome() { fmt.Println() fmt.Println( 图书管理系统 v1.0 - 图书录入器) fmt.Println() fmt.Printf( 格式书名,作者,价格\n) fmt.Printf( 输入 %s 退出\n, exitCmd) fmt.Printf( 数据保存到 %s\n, dataFile) fmt.Println() } // parseInput 按逗号分割输入返回书名、作者、价格字符串 func parseInput(input string) (title, author, price string, err error) { parts : strings.Split(input, ,) if len(parts) ! 3 { return , , , fmt.Errorf(需要3个字段实际%d个, len(parts)) } return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), strings.TrimSpace(parts[2]), nil } // validateTitle 校验书名不能为空 func validateTitle(title string) error { if title { return fmt.Errorf(书名不能为空) } return nil } // validateAuthor 校验作者不能为空 func validateAuthor(author string) error { if author { return fmt.Errorf(作者不能为空) } return nil } // parsePrice 解析价格必须为数字且 0 func parsePrice(priceStr string) (float64, error) { price, err : strconv.ParseFloat(priceStr, 64) if err ! nil { return 0, fmt.Errorf(价格格式错误) } if price 0 { return 0, fmt.Errorf(价格不能为负数) } return price, nil } // // 备选交互方式fmt.Scanln注释掉供参考对比 // 优点写法简洁缺点无法处理带空格的输入 // // var title, author, priceStr string // fmt.Print(请输入书名: ) // fmt.Scanln(title) // fmt.Print(请输入作者: ) // fmt.Scanln(author) // fmt.Print(请输入价格: ) // fmt.Scanln(priceStr) // // 本案例知识点 // 变量/常量 | if/for | 函数多返回值 | error处理 | 文件操作 | 字符串处理 // 三、测试代码精简版文件路径case1/main_test.gogo复制下载package main import testing // 测试价格解析 func TestParsePrice(t *testing.T) { tests : []struct { name string input string want float64 ok bool // true表示期望成功 }{ {正常价格, 59.00, 59.00, true}, {整数, 59, 59.00, true}, {零元, 0, 0, true}, {负数, -10, 0, false}, {非数字, abc, 0, false}, } for _, tt : range tests { t.Run(tt.name, func(t *testing.T) { got, err : parsePrice(tt.input) if tt.ok err ! nil { t.Errorf(期望成功但返回错误: %v, err) } if !tt.ok err nil { t.Errorf(期望失败但成功了) } if tt.ok got ! tt.want { t.Errorf(got %f, want %f, got, tt.want) } }) } } // 测试书名校验 func TestValidateTitle(t *testing.T) { err : validateTitle() if err nil { t.Error(空书名应该返回错误) } err validateTitle(Go语言) if err ! nil { t.Errorf(正常书名不应该返回错误: %v, err) } } // 测试输入解析 func TestParseInput(t *testing.T) { title, author, price, err : parseInput(Go语言,张三,59.00) if err ! nil { t.Errorf(解析失败: %v, err) } if title ! Go语言 || author ! 张三 || price ! 59.00 { t.Errorf(解析结果不符: %s, %s, %s, title, author, price) } _, _, _, err parseInput(Go语言,张三) if err nil { t.Error(字段不足应该返回错误) } } // 运行测试go test -v // 运行指定测试go test -v -run TestParsePrice四、运行指南bash复制下载# 运行程序 cd case1 go run main.go # 运行测试 go test -v # 测试覆盖率 go test -v -cover五、交互示例text复制下载 图书管理系统 v1.0 - 图书录入器 格式书名,作者,价格 输入 quit 退出 数据保存到 books.txt 请输入书名,作者,价格输入 quit 退出: Go语言实战,张三,59.00 ✅ 第 1 本录入成功: Go语言实战,张三,59.00 请输入书名,作者,价格输入 quit 退出: ,王五,30 ❌ 书名不能为空 请输入书名,作者,价格输入 quit 退出: 测试书,赵六,-10 ❌ 价格不能为负数 请输入书名,作者,价格输入 quit 退出: quit ✅ 共录入 1 本图书已保存到 books.txt六、案例1 → 案例2 衔接text复制下载 案例1结束案例2衔接说明 1. 本案例已学知识点 ✅ 变量/常量、基本类型 ✅ if/else、for循环、break ✅ 函数定义与多返回值 ✅ error错误处理 ✅ 文件操作os.OpenFile、defer ✅ 缓冲写入bufio.Writer ✅ 字符串处理TrimSpace、Split ✅ 类型转换strconv.ParseFloat ✅ 单元测试表驱动测试、t.Run 2. 案例2将升级 books.txt → books.json结构化数据 单文件 → 多包分层model/repository/handler 仅录入 → 完整CRUD增删改查 3. 本案例后续可优化将在案例2中实现 用结构体代替分散的字符串变量 用JSON替代纯文本支持结构化存储 增加查询、更新、删除功能 增加内存存储提高操作效率