- 博主简介:努力学习的大一在校计算机专业学生,热爱学习和创作。目前在学习和分享:数据结构、Go,Java等相关知识。
- 博主主页: @是瑶瑶子啦
- 所属专栏: Go语言核心编程
- 近期目标:写好专栏的每一篇文章
一、备忘录程序介绍前几天瑶瑶子学习了Go语言的基础语法知识,那么今天我们就写个小项目来练练手吧
有以下5个功能
- 查询所有备忘录
- 新增一个备忘录
- 删除备忘录
- 更新备忘录
- 退出备忘录
二、功能分析和实现下面详细讲解是以备忘录的标题为索引,即通过备忘录标题来查找对应备忘录内容(文章最后会附上用序号来查找的版本)
前言
这里我的想法是一条备忘录分为两个模块
- 备忘录标题
- 备忘录内容
mapmemoHeadmemoContent
还有一种方案是采用map+数组+结构体存储,利用下标索引进行操作备忘录,这种方法的代码我会在最后附上
2.1:开始菜单
- 在程序开始执行,需要向用户打印操作菜单,这个比较简单,我们可以吧打印菜单的操作封装到一个函数中:
package mainimport "fmt"func printMenu() {menuInfo := `****************************************1、查询所有备忘录2、新增一条备忘录3、删除指定备忘录4、更新某项备忘录5、退出备忘录****************************************
`fmt.Print(menuInfo)
}func main() {printMenu()
}
看下效果:
这里我们使用了Go语言特有的字符串赋值方式:使用反引号,引起多行字符串
2.2:输入并且读入操作数
那么Go语言是如何从控制台读取用户键盘输入的数据呢?
fmtbufiofmtScanSscanbufioNewScannerReadString
fmt
package mainimport "fmt"func main() {var name stringvar age intfmt.Print("请输入姓名:")fmt.Scanln(&name)fmt.Print("请输入年龄:")fmt.Scanln(&age)fmt.Printf("您好,%s,您的年龄是%d岁。\n", name, age)
}
Scanln&
bufio
package mainimport ("bufio""fmt""os"
)func main() {reader := bufio.NewReader(os.Stdin)fmt.Print("请输入字符串:")str, _ := reader.ReadString('\n')fmt.Printf("您输入的字符串是:%s\n", str)fmt.Print("请输入整数:")var num int_, err := fmt.Fscanf(reader, "%d", &num)if err != nil {fmt.Println(err)return}fmt.Printf("您输入的整数是:%d\n", num)
}
NewReaderbufio.ReaderReadStringFscanfFscanf&
这里两种输入方法都是完全可以的,我们采用第二种输入方法:
func main() {printMenu()reader := bufio.NewReader(os.Stdin) //使用bufio包中的NewReader函数创建了一个bufio.Reader对象//func NewReader(rd io.Reader) *Reader,NewReader创建一个具有默认大小缓冲、从r读取的*Reader//os.Stdin是指从操作系统的标准输入缓冲区读取input, _ := reader.ReadString('\n') //会读取第一次遇到'\n,之前的数据input = strings.TrimSpace(input) //返回将s前后端所有空白(unicode.IsSpace指定)都去掉的字符串。
}
2.3:流程控制
根据输入,进行流程控制,选择相应功能:
这里用switch-case分支结构即可
switch 语句是一个选择语句,用于将 switch 后的表达式的值与可能匹配的选项 case 后的表达式进行比较,并根据匹配情况执行相应的代码块,执行完匹配的代码块后,直接退出 switch-case 。如果没有任何一个匹配,就会执行 default 的代码块。它可以被认为是替代多个 if-else 子句的常用方式。和其他语言不同的是,这里的case并不是入口,所以不需要在每个case后面加上break!
func main() {for {printMenu()reader := bufio.NewReader(os.Stdin) //使用bufio包中的NewReader函数创建了一个bufio.Reader对象//func NewReader(rd io.Reader) *Reader,NewReader创建一个具有默认大小缓冲、从r读取的*Reader//os.Stdin是指从操作系统的标准输入缓冲区读取input, _ := reader.ReadString('\n') //会读取第一次遇到'\n,包括'\n'之前的数据input = strings.TrimSpace(input) //返回将s前后端所有空白(unicode.IsSpace指定)都去掉的字符串。switch input {case "1":printAllMenos() //查询并打印所有的备忘录case "2": //新增备忘录//输入、读取备忘录标题和内容fmt.Print("请输入备忘录标题:")memoHead, _ := reader.ReadString('\n')fmt.Print("请输入备忘录内容:")memoContent, _ := reader.ReadString('\n')//保存至memosaddMemo(memoHead, memoContent)case "3": //删除备忘录fmt.Print("请输入要删除的备忘录标题:")memoHead, _ := reader.ReadString('\n')//先在备忘录中查找是否存在//判断key是否存在:_, ok := memos[memoHead]if ok {deleteMemo(memoHead)} else {fmt.Println("err:不存在该标题的备忘录!")}case "4": //更新备忘录fmt.Print("请输入要更新的备忘录标题:")memoHead, _ := reader.ReadString('\n')//先在备忘录中查找是否存在//判断key是否存在:_, ok := memos[memoHead]if ok {updateMemo(memoHead) //更新} else {fmt.Println("err:不存在该标题的备忘录!")}case "5":fmt.Println("*************退出备忘录***********")os.Exit(0) //退出程序default:fmt.Println("err:输入数字不合法,请重新选择!")}}
}
外面套了个for,循环,当输入5:“退出备忘录程序”时,将退出程序
2.3:查询备忘录功能
func printAllMenos() {if len(memos) == 0 {fmt.Println("****当前备忘录为空φ(* ̄0 ̄)****")return}fmt.Printf("当前有 %d 条备忘录,所有备忘录如下:\n", len(memos))//进行map变量for memoHead, memoContent := range memos {fmt.Printf("memoHead : %smemoContent: %s", memoHead, memoContent)fmt.Println("**********************************************")}
}
2.4:新增备忘录
ps:这里将我采用将备忘录保存至map
case "2": //新增备忘录//输入、读取备忘录标题和内容fmt.Print("请输入备忘录标题:")memoHead, _ := reader.ReadString('\n')fmt.Print("请输入备忘录内容:")memoContent, _ := reader.ReadString('\n')//保存至memosaddMemo(memoHead, memoContent)
func addMemo(memoHead string, memoContent string) {//给map添加元素memos[memoHead] = memoContentfmt.Println("新增备忘录成功O(∩_∩)O")
}
2.5:删除备忘录
ps:这里我是根据备忘录的标题来删除相应备忘录的。所以请将流程图的序号看作标题即可
case "3": //删除备忘录fmt.Print("请输入要删除的备忘录标题:")memoHead, _ := reader.ReadString('\n')//先在备忘录中查找是否存在//判断key是否存在:_, ok := memos[memoHead]if ok {deleteMemo(memoHead)} else {fmt.Println("o((>ω< ))oerr:不存在该标题的备忘录!")}
func deleteMemo(memoHead string) {delete(memos, memoHead)fmt.Println("删除备忘录成功(❤ ω ❤)")
}
2.6:更新备忘录
case "4": //更新备忘录fmt.Print("请输入要更新的备忘录标题:")memoHead, _ := reader.ReadString('\n')//先在备忘录中查找是否存在//判断key是否存在:_, ok := memos[memoHead]if ok {updateMemo(memoHead) //更新} else {fmt.Println("o((>ω< ))oerr:不存在该标题的备忘录!")}
func updateMemo(memoHead string) {reader := bufio.NewReader(os.Stdin)newMemoContent, _ := reader.ReadString('\n')memos[memoHead] = newMemoContentfmt.Println("更新备忘录成功(●ˇ∀ˇ●)")
}
2.7:退出程序
case "5":fmt.Println("*************退出备忘录***********")os.Exit(0) //退出程序
三、完整代码
3.1:根据标题索引
package mainimport ("bufio""fmt""os""strings"
)// 使用make函数创建一个map,用来存储所有备忘录(注意,全局变量在函数外,不能用短声明:“:=”
var memos = make(map[string]string)func printMenu() {menuInfo := `****************************************1、查询所有备忘录2、新增一条备忘录3、删除指定备忘录4、更新某项备忘录5、退出备忘录****************************************
`fmt.Print(menuInfo)
}func main() {for {printMenu()reader := bufio.NewReader(os.Stdin) //使用bufio包中的NewReader函数创建了一个bufio.Reader对象//func NewReader(rd io.Reader) *Reader,NewReader创建一个具有默认大小缓冲、从r读取的*Reader//os.Stdin是指从操作系统的标准输入缓冲区读取input, _ := reader.ReadString('\n') //会读取第一次遇到'\n,包括'\n'之前的数据input = strings.TrimSpace(input) //返回将s前后端所有空白(unicode.IsSpace指定)都去掉的字符串。switch input {case "1":printAllMemos() //查询并打印所有的备忘录case "2": //新增备忘录//输入、读取备忘录标题和内容fmt.Print("请输入备忘录标题:")memoHead, _ := reader.ReadString('\n')fmt.Print("请输入备忘录内容:")memoContent, _ := reader.ReadString('\n')//保存至memosaddMemo(memoHead, memoContent)case "3": //删除备忘录fmt.Print("请输入要删除的备忘录标题:")memoHead, _ := reader.ReadString('\n')//先在备忘录中查找是否存在//判断key是否存在:_, ok := memos[memoHead]if ok {deleteMemo(memoHead)} else {fmt.Println("o((>ω< ))oerr:不存在该标题的备忘录!")}case "4": //更新备忘录fmt.Print("请输入要更新的备忘录标题:")memoHead, _ := reader.ReadString('\n')//先在备忘录中查找是否存在//判断key是否存在:_, ok := memos[memoHead]if ok {updateMemo(memoHead) //更新} else {fmt.Println("o((>ω< ))oerr:不存在该标题的备忘录!")}case "5":fmt.Println("*************退出备忘录***********")os.Exit(0) //退出程序default:fmt.Println("o((>ω< ))oerr:输入数字不合法,请重新选择!")}}
}func printAllMemos() {if len(memos) == 0 {fmt.Println("****当前备忘录为空φ(* ̄0 ̄)****")return}fmt.Printf("当前有 %d 条备忘录,所有备忘录如下:\n", len(memos))//进行map遍历for memoHead, memoContent := range memos {fmt.Printf("memoHead : %smemoContent: %s", memoHead, memoContent)fmt.Println("**********************************************")}
}func addMemo(memoHead string, memoContent string) {//给map添加元素memos[memoHead] = memoContentfmt.Println("新增备忘录成功O(∩_∩)O")
}func deleteMemo(memoHead string) {delete(memos, memoHead)fmt.Println("删除备忘录成功(❤ ω ❤)")
}
func updateMemo(memoHead string) {reader := bufio.NewReader(os.Stdin)fmt.Print("请输入新备忘录内容:")newMemoContent, _ := reader.ReadString('\n')memos[memoHead] = newMemoContentfmt.Println("更新备忘录成功(●ˇ∀ˇ●)")
}
3.2:优化:根据序号索引
根据序号索引,则不用只是用map来存储,而用:map+数组+结构体来存储
package mainimport ("bufio""fmt""os""strconv""strings"
)// 使用数组来存储,结构体// 定义一个备忘录结构体
type Memo struct {Head stringContent string
}// 存储所有备忘录的数组,序号是备忘录索引
var memos map[int]Memo = make(map[int]Memo)var lastID intfunc printMenu() {menuInfo := `****************************************1、查询所有备忘录2、新增一条备忘录3、删除指定备忘录4、更新某项备忘录5、退出备忘录****************************************
`fmt.Print(menuInfo)
}func main() {for {printMenu()reader := bufio.NewReader(os.Stdin) //使用bufio包中的NewReader函数创建了一个bufio.Reader对象//func NewReader(rd io.Reader) *Reader,NewReader创建一个具有默认大小缓冲、从r读取的*Reader//os.Stdin是指从操作系统的标准输入缓冲区读取input, _ := reader.ReadString('\n') //会读取第一次遇到'\n,包括'\n'之前的数据input = strings.TrimSpace(input) //返回将s前后端所有空白(unicode.IsSpace指定)都去掉的字符串。switch input {case "1":printAllMemos() //查询并打印所有的备忘录case "2": //新增备忘录//输入、读取备忘录标题和内容fmt.Print("请输入备忘录标题:")memoHead, _ := reader.ReadString('\n')fmt.Print("请输入备忘录内容:")memoContent, _ := reader.ReadString('\n')//保存至memosaddMemo(memoHead, memoContent)case "3": //删除备忘录fmt.Print("请输入要删除的备忘录序号:")id, _ := reader.ReadString('\n')id = strings.TrimSpace(id)//将字符串转成整数index, err := strconv.Atoi(id)//判断输入序号是否合法if err != nil {fmt.Println(">﹏<输入序号不合法")}_, ok := memos[index] //看该序号对应的备忘录是否存在if ok {deleteMemo(index)} else {fmt.Println("(;´д`)ゞ输入的序号不存在")}case "4": //更新备忘录fmt.Print("请输入要更新的备忘录序号:")id, _ := reader.ReadString('\n')id = strings.TrimSpace(id)//将字符串转成整数index, err := strconv.Atoi(id)//判断输入序号是否合法if err != nil {fmt.Println(">﹏<输入序号不合法")}_, ok := memos[index] //看该序号对应的备忘录是否存在if ok {updateMemo(index)} else {fmt.Println("(;´д`)ゞ输入的序号不存在")}case "5":fmt.Println("*************退出备忘录***********")os.Exit(0) //退出程序default:fmt.Println("o((>ω< ))oerr:输入数字不合法,请重新选择!")}}
}func printAllMemos() {if len(memos) == 0 {fmt.Println("****当前备忘录为空φ(* ̄0 ̄)****")return}fmt.Printf("当前有 %d 条备忘录,所有备忘录如下:\n", len(memos))//遍历for id, memo := range memos {fmt.Printf("ID : %d memoHead : %smemoContent: %s", id, memo.Head, memo.Content)fmt.Println("**********************************************")}
}func addMemo(memoHead string, memoContent string) {lastID++//为该条新备忘录创建一个实体memo := Memo{Head: memoHead, Content: memoContent}memos[lastID] = memofmt.Println("新增备忘录成功O(∩_∩)O")
}func deleteMemo(id int) {delete(memos, id)fmt.Println("删除备忘录成功(❤ ω ❤)")
}
func updateMemo(id int) {reader := bufio.NewReader(os.Stdin)fmt.Printf("请更新%d号备忘录的标题:", id)newMemoHead, _ := reader.ReadString('\n')fmt.Printf("请更新%d号备忘录的内容:", id)newMemoContent, _ := reader.ReadString('\n')//将数据更新memo := Memo{Head: newMemoHead, Content: newMemoContent}memos[id] = memofmt.Println("更新备忘录成功(●ˇ∀ˇ●)")
}
效果展示:
💁🏻♀️上面是一个Go语言实现的通讯录小项目,非常适合拿来练手,整合Go的基础知识
欢迎在评论区交流和留下你的想法和建议
如果对你有用,还请:💭评论+👍🏻点赞+⭐收藏+➕关注
- Java岛冒险记【从小白到大佬之路】
- LeetCode每日一题–进击大厂
- 算法
- C/C++
- Go语言核心编程
- 数据结构