【Golang项目实战】手把手教你写一个备忘录程序|附源码——建议收藏
- 博主簡介:努力學(xué)習(xí)的大一在校計算機專業(yè)學(xué)生,熱愛學(xué)習(xí)和創(chuàng)作。目前在學(xué)習(xí)和分享:數(shù)據(jù)結(jié)構(gòu)、Go,Java等相關(guān)知識。
- 博主主頁: @是瑤瑤子啦
- 所屬專欄: Go語言核心編程
- 近期目標(biāo):寫好專欄的每一篇文章
前幾天瑤瑤子學(xué)習(xí)了Go語言的基礎(chǔ)語法知識,那么今天我們就寫個小項目來練練手吧
目錄
- 一、備忘錄程序介紹
- 二、功能分析和實現(xiàn)
- 前言
- 2.1:開始菜單
- 2.2:輸入并且讀入操作數(shù)
- 2.3:流程控制
- 2.3:查詢備忘錄功能
- 2.4:新增備忘錄
- 2.5:刪除備忘錄
- 2.6:更新備忘錄
- 2.7:退出程序
- 三、完整代碼
- 3.1:根據(jù)標(biāo)題索引
- 3.2:優(yōu)化:根據(jù)序號索引
- 效果展示:
一、備忘錄程序介紹
有以下5個功能
- 查詢所有備忘錄
- 新增一個備忘錄
- 刪除備忘錄
- 更新備忘錄
- 退出備忘錄
下面詳細(xì)講解是以備忘錄的標(biāo)題為索引,即通過備忘錄標(biāo)題來查找對應(yīng)備忘錄內(nèi)容(文章最后會附上用序號來查找的版本)
二、功能分析和實現(xiàn)
前言
這里我的想法是一條備忘錄分為兩個模塊
- 備忘錄標(biāo)題
- 備忘錄內(nèi)容
用map容器存儲備忘錄,其中備忘錄標(biāo)題memoHead作為key,備忘錄內(nèi)容memoContent作為value
還有一種方案是采用map+數(shù)組+結(jié)構(gòu)體存儲,利用下標(biāo)索引進行操作備忘錄,這種方法的代碼我會在最后附上
2.1:開始菜單
- 在程序開始執(zhí)行,需要向用戶打印操作菜單,這個比較簡單,我們可以吧打印菜單的操作封裝到一個函數(shù)中:
看下效果:
這里我們使用了Go語言特有的字符串賦值方式:使用反引號,引起多行字符串
2.2:輸入并且讀入操作數(shù)
那么Go語言是如何從控制臺讀取用戶鍵盤輸入的數(shù)據(jù)呢?
在Go語言中,可以使用標(biāo)準(zhǔn)庫fmt和bufio進行控制臺輸入。其中,fmt包提供了Scan系列函數(shù)和Sscan系列函數(shù),bufio包提供了NewScanner函數(shù)和ReadString函數(shù)等。
上面的代碼使用了Scanln函數(shù)讀取控制臺輸入,并使用&操作符將輸入的值存儲到相應(yīng)的變量中。
fmt.Scanln 函數(shù)不需要指定格式字符串,它會自動根據(jù)空格分割輸入,并將每個部分解析為對應(yīng)的數(shù)據(jù)類型。
在讀取輸入后會自動清除輸入流緩存中的換行符,因此下一次輸入不會受到影響。
上面的代碼使用了NewReader函數(shù)創(chuàng)建了一個bufio.Reader對象,使用ReadString函數(shù)讀取輸入的字符串,使用Fscanf函數(shù)讀取輸入的整數(shù)。注意,在使用Fscanf函數(shù)讀取整數(shù)時,需要使用&操作符將變量的地址傳遞給函數(shù)。
這里兩種輸入方法都是完全可以的,我們采用第二種輸入方法:
func main() {printMenu()reader := bufio.NewReader(os.Stdin) //使用bufio包中的NewReader函數(shù)創(chuàng)建了一個bufio.Reader對象//func NewReader(rd io.Reader) *Reader,NewReader創(chuàng)建一個具有默認(rèn)大小緩沖、從r讀取的*Reader//os.Stdin是指從操作系統(tǒng)的標(biāo)準(zhǔn)輸入緩沖區(qū)讀取input, _ := reader.ReadString('\n') //會讀取第一次遇到'\n,之前的數(shù)據(jù)input = strings.TrimSpace(input) //返回將s前后端所有空白(unicode.IsSpace指定)都去掉的字符串。 }2.3:流程控制
根據(jù)輸入,進行流程控制,選擇相應(yīng)功能:
這里用switch-case分支結(jié)構(gòu)即可switch 語句是一個選擇語句,用于將 switch 后的表達式的值與可能匹配的選項 case 后的表達式進行比較,并根據(jù)匹配情況執(zhí)行相應(yīng)的代碼塊,執(zhí)行完匹配的代碼塊后,直接退出 switch-case 。如果沒有任何一個匹配,就會執(zhí)行 default 的代碼塊。它可以被認(rèn)為是替代多個 if-else 子句的常用方式。和其他語言不同的是,這里的case并不是入口,所以不需要在每個case后面加上break!
func main() {for {printMenu()reader := bufio.NewReader(os.Stdin) //使用bufio包中的NewReader函數(shù)創(chuàng)建了一個bufio.Reader對象//func NewReader(rd io.Reader) *Reader,NewReader創(chuàng)建一個具有默認(rèn)大小緩沖、從r讀取的*Reader//os.Stdin是指從操作系統(tǒng)的標(biāo)準(zhǔn)輸入緩沖區(qū)讀取input, _ := reader.ReadString('\n') //會讀取第一次遇到'\n,包括'\n'之前的數(shù)據(jù)input = strings.TrimSpace(input) //返回將s前后端所有空白(unicode.IsSpace指定)都去掉的字符串。switch input {case "1":printAllMenos() //查詢并打印所有的備忘錄case "2": //新增備忘錄//輸入、讀取備忘錄標(biāo)題和內(nèi)容fmt.Print("請輸入備忘錄標(biāo)題:")memoHead, _ := reader.ReadString('\n')fmt.Print("請輸入備忘錄內(nèi)容:")memoContent, _ := reader.ReadString('\n')//保存至memosaddMemo(memoHead, memoContent)case "3": //刪除備忘錄fmt.Print("請輸入要刪除的備忘錄標(biāo)題:")memoHead, _ := reader.ReadString('\n')//先在備忘錄中查找是否存在//判斷key是否存在:_, ok := memos[memoHead]if ok {deleteMemo(memoHead)} else {fmt.Println("err:不存在該標(biāo)題的備忘錄!")}case "4": //更新備忘錄fmt.Print("請輸入要更新的備忘錄標(biāo)題:")memoHead, _ := reader.ReadString('\n')//先在備忘錄中查找是否存在//判斷key是否存在:_, ok := memos[memoHead]if ok {updateMemo(memoHead) //更新} else {fmt.Println("err:不存在該標(biāo)題的備忘錄!")}case "5":fmt.Println("*************退出備忘錄***********")os.Exit(0) //退出程序default:fmt.Println("err:輸入數(shù)字不合法,請重新選擇!")}} }外面套了個for,循環(huán),當(dāng)輸入5:“退出備忘錄程序”時,將退出程序
2.3:查詢備忘錄功能
func printAllMenos() {if len(memos) == 0 {fmt.Println("****當(dāng)前備忘錄為空φ(* ̄0 ̄)****")return}fmt.Printf("當(dāng)前有 %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": //新增備忘錄//輸入、讀取備忘錄標(biāo)題和內(nèi)容fmt.Print("請輸入備忘錄標(biāo)題:")memoHead, _ := reader.ReadString('\n')fmt.Print("請輸入備忘錄內(nèi)容:")memoContent, _ := reader.ReadString('\n')//保存至memosaddMemo(memoHead, memoContent) func addMemo(memoHead string, memoContent string) {//給map添加元素memos[memoHead] = memoContentfmt.Println("新增備忘錄成功O(∩_∩)O") }2.5:刪除備忘錄
ps:這里我是根據(jù)備忘錄的標(biāo)題來刪除相應(yīng)備忘錄的。所以請將流程圖的序號看作標(biāo)題即可
case "3": //刪除備忘錄fmt.Print("請輸入要刪除的備忘錄標(biāo)題:")memoHead, _ := reader.ReadString('\n')//先在備忘錄中查找是否存在//判斷key是否存在:_, ok := memos[memoHead]if ok {deleteMemo(memoHead)} else {fmt.Println("o((>ω< ))oerr:不存在該標(biāo)題的備忘錄!")} func deleteMemo(memoHead string) {delete(memos, memoHead)fmt.Println("刪除備忘錄成功(? ω ?)") }2.6:更新備忘錄
case "4": //更新備忘錄fmt.Print("請輸入要更新的備忘錄標(biāo)題:")memoHead, _ := reader.ReadString('\n')//先在備忘錄中查找是否存在//判斷key是否存在:_, ok := memos[memoHead]if ok {updateMemo(memoHead) //更新} else {fmt.Println("o((>ω< ))oerr:不存在該標(biāo)題的備忘錄!")} 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:根據(jù)標(biāo)題索引
package mainimport ("bufio""fmt""os""strings" )// 使用make函數(shù)創(chuàng)建一個map,用來存儲所有備忘錄(注意,全局變量在函數(shù)外,不能用短聲明:“:=” 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函數(shù)創(chuàng)建了一個bufio.Reader對象//func NewReader(rd io.Reader) *Reader,NewReader創(chuàng)建一個具有默認(rèn)大小緩沖、從r讀取的*Reader//os.Stdin是指從操作系統(tǒng)的標(biāo)準(zhǔn)輸入緩沖區(qū)讀取input, _ := reader.ReadString('\n') //會讀取第一次遇到'\n,包括'\n'之前的數(shù)據(jù)input = strings.TrimSpace(input) //返回將s前后端所有空白(unicode.IsSpace指定)都去掉的字符串。switch input {case "1":printAllMemos() //查詢并打印所有的備忘錄case "2": //新增備忘錄//輸入、讀取備忘錄標(biāo)題和內(nèi)容fmt.Print("請輸入備忘錄標(biāo)題:")memoHead, _ := reader.ReadString('\n')fmt.Print("請輸入備忘錄內(nèi)容:")memoContent, _ := reader.ReadString('\n')//保存至memosaddMemo(memoHead, memoContent)case "3": //刪除備忘錄fmt.Print("請輸入要刪除的備忘錄標(biāo)題:")memoHead, _ := reader.ReadString('\n')//先在備忘錄中查找是否存在//判斷key是否存在:_, ok := memos[memoHead]if ok {deleteMemo(memoHead)} else {fmt.Println("o((>ω< ))oerr:不存在該標(biāo)題的備忘錄!")}case "4": //更新備忘錄fmt.Print("請輸入要更新的備忘錄標(biāo)題:")memoHead, _ := reader.ReadString('\n')//先在備忘錄中查找是否存在//判斷key是否存在:_, ok := memos[memoHead]if ok {updateMemo(memoHead) //更新} else {fmt.Println("o((>ω< ))oerr:不存在該標(biāo)題的備忘錄!")}case "5":fmt.Println("*************退出備忘錄***********")os.Exit(0) //退出程序default:fmt.Println("o((>ω< ))oerr:輸入數(shù)字不合法,請重新選擇!")}} }func printAllMemos() {if len(memos) == 0 {fmt.Println("****當(dāng)前備忘錄為空φ(* ̄0 ̄)****")return}fmt.Printf("當(dāng)前有 %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("請輸入新備忘錄內(nèi)容:")newMemoContent, _ := reader.ReadString('\n')memos[memoHead] = newMemoContentfmt.Println("更新備忘錄成功(●ˇ?ˇ●)") }3.2:優(yōu)化:根據(jù)序號索引
根據(jù)序號索引,則不用只是用map來存儲,而用:map+數(shù)組+結(jié)構(gòu)體來存儲
package mainimport ("bufio""fmt""os""strconv""strings" )// 使用數(shù)組來存儲,結(jié)構(gòu)體// 定義一個備忘錄結(jié)構(gòu)體 type Memo struct {Head stringContent string }// 存儲所有備忘錄的數(shù)組,序號是備忘錄索引 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函數(shù)創(chuàng)建了一個bufio.Reader對象//func NewReader(rd io.Reader) *Reader,NewReader創(chuàng)建一個具有默認(rèn)大小緩沖、從r讀取的*Reader//os.Stdin是指從操作系統(tǒng)的標(biāo)準(zhǔn)輸入緩沖區(qū)讀取input, _ := reader.ReadString('\n') //會讀取第一次遇到'\n,包括'\n'之前的數(shù)據(jù)input = strings.TrimSpace(input) //返回將s前后端所有空白(unicode.IsSpace指定)都去掉的字符串。switch input {case "1":printAllMemos() //查詢并打印所有的備忘錄case "2": //新增備忘錄//輸入、讀取備忘錄標(biāo)題和內(nèi)容fmt.Print("請輸入備忘錄標(biāo)題:")memoHead, _ := reader.ReadString('\n')fmt.Print("請輸入備忘錄內(nèi)容:")memoContent, _ := reader.ReadString('\n')//保存至memosaddMemo(memoHead, memoContent)case "3": //刪除備忘錄fmt.Print("請輸入要刪除的備忘錄序號:")id, _ := reader.ReadString('\n')id = strings.TrimSpace(id)//將字符串轉(zhuǎn)成整數(shù)index, err := strconv.Atoi(id)//判斷輸入序號是否合法if err != nil {fmt.Println(">﹏<輸入序號不合法")}_, ok := memos[index] //看該序號對應(yīng)的備忘錄是否存在if ok {deleteMemo(index)} else {fmt.Println("(;′д`)ゞ輸入的序號不存在")}case "4": //更新備忘錄fmt.Print("請輸入要更新的備忘錄序號:")id, _ := reader.ReadString('\n')id = strings.TrimSpace(id)//將字符串轉(zhuǎn)成整數(shù)index, err := strconv.Atoi(id)//判斷輸入序號是否合法if err != nil {fmt.Println(">﹏<輸入序號不合法")}_, ok := memos[index] //看該序號對應(yīng)的備忘錄是否存在if ok {updateMemo(index)} else {fmt.Println("(;′д`)ゞ輸入的序號不存在")}case "5":fmt.Println("*************退出備忘錄***********")os.Exit(0) //退出程序default:fmt.Println("o((>ω< ))oerr:輸入數(shù)字不合法,請重新選擇!")}} }func printAllMemos() {if len(memos) == 0 {fmt.Println("****當(dāng)前備忘錄為空φ(* ̄0 ̄)****")return}fmt.Printf("當(dāng)前有 %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++//為該條新備忘錄創(chuàng)建一個實體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號備忘錄的標(biāo)題:", id)newMemoHead, _ := reader.ReadString('\n')fmt.Printf("請更新%d號備忘錄的內(nèi)容:", id)newMemoContent, _ := reader.ReadString('\n')//將數(shù)據(jù)更新memo := Memo{Head: newMemoHead, Content: newMemoContent}memos[id] = memofmt.Println("更新備忘錄成功(●ˇ?ˇ●)") }效果展示:
💁🏻?♀?上面是一個Go語言實現(xiàn)的通訊錄小項目,非常適合拿來練手,整合Go的基礎(chǔ)知識
歡迎在評論區(qū)交流和留下你的想法和建議
如果對你有用,還請:💭評論+👍🏻點贊+?收藏+?關(guān)注
- Java島冒險記【從小白到大佬之路】
- LeetCode每日一題–進擊大廠
- 算法
- C/C++
- Go語言核心編程
- 數(shù)據(jù)結(jié)構(gòu)
總結(jié)
以上是生活随笔為你收集整理的【Golang项目实战】手把手教你写一个备忘录程序|附源码——建议收藏的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PTA天梯20+深度优先搜索及动态规划
- 下一篇: 牛客练习赛20 托米历险记