在 Golang 中,for
是唯一的迴圈語法,雖然看起來不像其他語言中的 while
或 do-while
,但透過靈活的表現方式,for
也能完成相同的功能。接下來將會介紹 Golang 中 for
的用法,並比較與 while
迴圈的不同,同時探討如何有效避免過度複雜的迴圈邏輯。
for
迴圈的基本結構如下:for 初始化語句; 條件判斷; 更新語句 {
// 迴圈內的程式邏輯
}
for i := 0; i < 5; i++ {
fmt.Println(i)
}
這樣的迴圈會從
i = 0
開始,當條件i < 5
成立時會繼續執行,並在每次執行後將i
加 1,直到條件不再成立。
break
與 continue
是控制迴圈執行流程的重要語法。
break
:用來中止整個迴圈。for i := 0; i < 10; i++ {
if i == 5 {
break // 當 i 等於 5 時,結束迴圈
}
fmt.Println(i)
}
continue
:用來跳過本次迴圈的剩餘部分,直接進入下一次迭代。for i := 0; i < 10; i++ {
if i%2 == 0 {
continue // 如果 i 是偶數,跳過當次迴圈
}
fmt.Println(i)
}
Range
在 Golang 中,我們經常需要遍歷陣列、切片、字典等資料結構,這時候 range
可以讓程式碼更簡潔。
下篇
介紹更為詳細的觀點)nums := []int{1, 2, 3, 4, 5}
for index, value := range nums {
fmt.Printf("索引: %d, 值: %d\n", index, value)
}
</* Output: */>
鍵: a, 值: 1
鍵: b, 值: 2
鍵: c, 值: 3
它依次遍歷字典的每個項目,並印出每個鍵和值。
第11天
中介紹更為詳細的觀點)dict := map[string]int{"a": 1, "b": 2, "c": 3}
for key, value := range dict {
fmt.Printf("鍵: %s, 值: %d\n", key, value)
}
</* Output: */>
索引: 0, 值: 1
索引: 1, 值: 2
索引: 2, 值: 3
索引: 3, 值: 4
索引: 4, 值: 5
它逐一取出切片的每個元素,並印出其索引與值。
在 Golang 中,for
可以模擬其他語言中的 while
迴圈。當省略初始化和更新語句時,for
的行為就像一個 while
迴圈。
while
的實現i := 0
for i < 5 { // 模擬 while 迴圈
fmt.Println(i)
i++
}
這樣的 for 迴圈沒有初始化語句和更新語句,單純依賴條件判斷,與其他語言的 while 十分相似。
For
迴圈:適合用於有確定次數的迭代,如遍歷陣列、切片等。While
迴圈 (模擬):適合不確定次數的迭代,直到某個條件達成為止。當迴圈邏輯變得複雜時,過度的包裝會讓程式碼難以閱讀與維護。此時,應考慮將部分邏輯抽取到函數中,保持迴圈內的邏輯簡單。
func processItem(item int) {
// 處理單一項目邏輯
fmt.Println("處理項目:", item)
}
nums := []int{1, 2, 3, 4, 5}
for _, num := range nums {
processItem(num) // 抽取複雜邏輯至獨立函數
}
如果不需要遍歷的 index 值時,也可以用 "_" 取代
這種改變會造成程式難以理解與除錯。例如,在迴圈內改變全域變數的值是一個常見的副作用,應盡量避免。
// FIXME: - 考慮將計算邏輯封裝在函數內,傳回計算結果
total := 0
nums := []int{1, 2, 3, 4, 5}
for _, num := range nums {
total += num // 改變外部變數 total
}
// TODO: - 改善方式
func sum(nums []int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
nums := []int{1, 2, 3, 4, 5}
result := sum(nums)
fmt.Println(result)
sum
函數內,total
是函數內部的變數,並不影響外部的狀態。讓程式碼更具可預測性和穩定性。迴圈只應該處理數據計算,不應同時處理顯示邏輯、資料庫存取等工作。
// FIXME: - 迴圈內同時處理資料和顯示邏輯
for i := 0; i < len(data); i++ {
processData(data[i])
fmt.Println("處理中的資料:", data[i]) // 顯示邏輯不應與處理邏輯混合
}
// TODO: - 將顯示邏輯抽取至外部
func displayData(data int) {
fmt.Println("處理中的資料:", data)
}
for i := 0; i < len(data); i++ {
processData(data[i]) // 只專注於處理資料
}
今天我們學習了 Golang 中唯一的迴圈語法 for
,其靈活性可以模擬其他語言中的 while
迴圈。我們介紹了 for
迴圈的基本結構,並且展示了如何使用 break
和 continue
控制迴圈流程。同時,我們學到了如何透過 range 簡潔地遍歷切片和字典。還有,為了避免迴圈邏輯過於複雜,我們探討了如何將邏輯抽取到函數中,並遵循單一職責原則 (SRP),確保迴圈僅專注於執行單一的責任,保持程式簡潔、易於維護。