Go語言可能會遇到的坑

Go語言可能會遇到的坑



點擊藍字關注 前端


閱讀本文大約須要3分鐘。java



最近在用go開發項目的過程當中忽然發現一個坑,尤爲是對於其它傳統語言轉來的人來講一不注意就掉坑裏了,話很少說,咱看代碼:python


 
 

1//writeToCSV
2func writeESDateToCSV(totalValues chan []string) {
3    f, err := os.Create("t_data_from_es.csv")
4    defer f.Close()
5    if err != nil {
6        panic(err)
7    }
8
9    w := csv.NewWriter(f)
10    w.Write(columns)
11
12    for {
13        select {
14        case row := <- totalValues:
15            //fmt.Printf("Write Count:%d log:%s\n",i, row)
16            w.Write(row)
17        case <- isSendEnd:
18            if len(totalValues) == 0 {
19                fmt.Println("------------------Write End-----------------")
20                break
21            }
22        }
23    }
24
25    w.Flush()
26    fmt.Println("-------------------------處理完畢-------------------------")
27    isWriteEnd <- true
28}
golang


當數據發送完畢,即isSendEnd不阻塞,且totalValues裏沒數據時,跳出for循環,這裏用了break。可是調試的時候發現,程序阻塞在了14行,即兩個channel都阻塞了。而後才驚覺這裏break不是這麼玩,而後寫了個測試方法測試一下:web


 
 

package main

import (
    "time"
    "fmt"
)

func main() {
    i := 0
    for {
        select {
        case <-time.After(time.Second * time.Duration(2)):
            i++
            if i == 5{
                fmt.Println("break now")
                break
            }
            fmt.Println("inside the select: ")
        }
        fmt.Println("inside the for: ")
    }

    fmt.Println("outside the for: ")
}
面試


運行輸出以下結果,break now以後仍是會繼續無限循環,不會跳出for循環,只是跳出了一次selectspring


 
 

inside the select
inside the for
inside the select
inside the for
inside the select
inside the for
inside the select
inside the for
break now
inside the for
inside the select
inside the for
inside the select
inside the for
inside the select
inside the for
docker



若要break出來,這裏須要加一個標籤,使用goto, 或者break 到具體的位置。編程



解決方法一:編輯器


使用golang中break的特性,在外層for加一個標籤:


 
 

package main

import (
    "time"
    "fmt"
)

func main() {
    i := 0

    endLoop:
    for {
        select {
        case <-time.After(time.Second * time.Duration(2)):
            i++
            if i == 5{
                fmt.Println("break now")
                break endLoop
            }
            fmt.Println("inside the select: ")
        }
        fmt.Println("inside the for: ")
    }

    fmt.Println("outside the for: ")
}



解決方法二: 


使用goto直接跳出循環:


 
 

package main

import (
    "time"
    "fmt"
)

func main() {
    i := 0
    for {
        select {
        case <-time.After(time.Second * time.Duration(2)):
            i++
            if i == 5{
                fmt.Println("break now")
                goto endLoop
            }
            fmt.Println("inside the select: ")
        }
        fmt.Println("inside the for: ")
    }
    endLoop:
    fmt.Println("outside the for: ")
}


兩程序運行輸出以下:


 
 

inside the select
inside the for
inside the select
inside the for
inside the select
inside the for
inside the select
inside the for
break now
outside the for

Process finished with exit code 0



綜上能夠得出:go語言的switch-case和select-case都是不須要break的,可是加上break也只是跳出本次switch或select,並不會跳出for循環。




go、docker、k8s等學習資源,可在文末公衆號後臺回覆【1】加小助手索取。



點擊下面進入送書活動傳送門:

送書、四本實體書籍 & 免費csdn下載


本文由「壹伴編輯器」提供技術支持

本公衆號免費提供csdn下載服務,海量IT學習資源,若是你準備入IT坑,勵志成爲優秀的程序猿,那麼這些資源很適合你,包括但不限於java、go、python、springcloud、elk、嵌入式 、大數據、面試資料、前端 等資源。同時咱們組建了一個技術交流羣,裏面有不少大佬,會不定時分享技術文章,若是你想來一塊兒學習提升,能夠公衆號後臺回覆2,免費邀請加技術交流羣互相學習提升,會不按期分享編程IT相關資源。


963b1f1b74f9edf36c9d6f27b3bcb3a8.webp

相關文章
相關標籤/搜索