在 go 中的 for 與其他語言的語法大致相似,但是有些地方有些不同,在 go 中 for 的完整寫法與在他與言一樣,定義某變數的初始值、結束條件、遞增表達式,但是不同的點是在 go 中是可以選擇性省略初始值、結束條件、遞增表達式的設定,而 for 中沒有 while ,是透過 for 來模擬 while 的方式,情況如下
func main() {
// 完整寫法
// fmt.Printf()與fmt.Println()相似,但是其中有一些差異
// 可以參考下面參考來源提供的第一個連結
fmt.Printf("完整寫法: ")
for i := 0; i < 10; i++ {
fmt.Printf("%d ", i) // 0 1 2 3 4 5 6 7 8 9
}
// 缺少初始值設定的寫法
fmt.Printf("缺少初始: ")
j := 0
for ; j < 10; j++ {
fmt.Printf("%d ", j) // 0 1 2 3 4 5 6 7 8 9
}
// 模擬 while 的方式
fmt.Printf("模擬寫法: ")
k := 0
for k < 10 {
fmt.Printf("%d ", k) // 0 1 2 3 4 5 6 7 8 9
k++
}
}
輸出結果為:
完整寫法: 0 1 2 3 4 5 6 7 8 9
缺少初始: 0 1 2 3 4 5 6 7 8 9
模擬寫法: 0 1 2 3 4 5 6 7 8 9
那根據 day03 的 map 迭代部分,這邊我們就可以使用 for 迴圈與 range 來完成這件事
type Nominate struct {
President string
VicePresident string
}
func main() {
electionCandidates := map[int]Nominate{
1: {"宋楚X", "余X"},
2: {"韓國X", "張善X"},
3: {"蔡英X", "賴清X"},
}
for i, v := range electionCandidates {
fmt.Printf("號次: %d, 總統候選人: %s, 副總統候選人: %s\n", i, v.President, v.VicePresident)
}
}
輸出結果為:(結果可能順序會不同,這是因為在 go 中 map的遍歷輸出的时候是無序的,不同的遍歷會有不同的輸出结果,如果想要顺序輸出的话,需要額外保存順序)
號次: 1, 總統候選人: 宋楚X, 副總統候選人: 余X
號次: 2, 總統候選人: 韓國X, 副總統候選人: 張善X
號次: 3, 總統候選人: 蔡英X, 副總統候選人: 賴清X
函數的聲明需要告訴有函數的名稱、參數與返回類型。函數的目的是為了將每個功能模組化,每個函數最好的定義方式就是只做一件事情。舉例來說,以2020年台灣的選舉來說,有三組總統與副總統候選人想要跟大家拜票,那麼我們可以定義利用上面的例子進行延伸舉例。函數的基本寫法為
func 函數名稱(參數名1 參數型態1, 參數名2 參數型態2, ...) (返回類型1, 返回類型2, ...) {
// TODO
}
type Nominate struct {
President string
VicePresident string
}
func main() {
electionCandidates := map[int]Nominate{
1: {"宋楚X", "余X"},
2: {"韓國X", "張善X"},
3: {"蔡英X", "賴清X"},
}
canvassing(electionCandidates, "正副總統", 2020)
}
// 函數名稱 (參數1 型態1, 參數2 型態2, 參數3 型態3) 返回類型1 {
func canvassing(candidates map[int]Nominate, title string, year int) string {
for i, v := range candidates {
fmt.Printf("%d 請大家多多支持??? %d號%s候選人~%s和%s,凍蒜!凍蒜!\n", year, i, title, v.President, v.VicePresident)
}
// 計算總候選組數
totalCandidates := len(candidates)
// 與fmt.Printf類似,詳情請見參考來源2
result := fmt.Sprintf("%d 總共有 %d 組%s候選人", year, totalCandidates, title)
return result
}
輸出結果為:
2020 請大家多多支持??? 1號正副總統候選人~宋楚X和余X,凍蒜!凍蒜!
2020 請大家多多支持??? 2號正副總統候選人~韓國X和張善X,凍蒜!凍蒜!
2020 請大家多多支持??? 3號正副總統候選人~蔡英X和賴清X,凍蒜!凍蒜!
2020 總共有 3 組總統候選人
那麼假設未來有其他需要拜票的話,我們只需要將參數所需的資料換一下就行了,比方說換成2022學校的學生會會長候選人
//type Nominate struct {
// President string
// VicePresident string
// }
// 與上面不同的就只有 main 裡面的東西,其他 func canvassing 與 type Nominate struct 都相同
// func main() {
electionCandidates := map[int]Nominate{
1: {"黃X", "林欣X"},
2: {"柯灃X", "蔡承X"},
}
output := canvassing(electionCandidates, "成大學生會正副會長", 2020)
// fmt.Println(output)
// }
// func canvassing(candidates map[int]Nominate, title string, year int) string {
// for i, v := range candidates {
// fmt.Printf("%d 請大家多多支持??? %d號%s候選人~%s和%s,凍蒜!凍蒜!\n", year, i, title, v.President, v.VicePresident)
// }
// totalCandidates := len(candidates)
// result := fmt.Sprintf("%d 總共有 %d 組%s候選人", year, totalCandidates, title)
// return result
// }
輸出結果為:
2020 請大家多多支持??? 1號成大學生會正副會長候選人~黃X和林欣X,凍蒜!凍蒜!
2020 請大家多多支持??? 2號成大學生會正副會長候選人~柯灃X和蔡承X,凍蒜!凍蒜!
2020 總共有 2 組成大學生會正副會長候選人
https://github.com/luckyuho/ithome30-golang/tree/main/day04