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