淺談Golang中select的用法

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

在go中,select主要是和channel有關,大概的格式如下:

select{case <- ch1:// do somethingcase i := <- ch2// use i do somethingdefault:// ...}

這個文法看起來和switch語句很接近,但是具體select有什麼用呢?我們來看一段代碼:

  • code-1
func main() {    ch := make(chan int)    for i := 0; i < 10; i++{        select {        case ch <- i:        case x := <- ch:            fmt.Println(x)        }    }}

這段代碼裡我們先建立了一個channel(管道),這個管道是無緩衝的,那麼這段代碼是否能正常的運行呢?

答案是不能的,這段代碼會產生一個deadlock

那麼我們稍微修改一下這個代碼,

ch := make(chan int, 1)

在這裡我們將剛才無緩衝的管道改變為有緩衝且緩衝大小為1的管道,再次運行之後,會顯示正確的結果,但是這個結果比較微妙:

02468

因為這個管道的緩衝值只有1,那麼同一時間只會有一個case執行,這個channel不是空的就是滿的。
所以這個結果是比較固定的,但是為什麼只會輸出這麼幾個數字呢?那我們來一起看看具體是怎麼啟動並執行。

在第一次進入迴圈的時候,i為0,進入到select中,開始由上向下來發現哪一個case可以執行,當計算運算式
ch <- i,也就是向管道寫入資料的時候,因為這個管道現在有緩衝,那麼在向管道寫完資料之後,此時的case便執行完成,然後就跳出select,開始進行下一次的迴圈,當i=1的時候(現在這個管道裡面的資料是0),再次進入select中,此時還是開始計算ch <- i 運算式,但是現在管道裡面是有資料的,再次向管道中寫入資料,那麼會使該發送操作阻塞,此時該case便無法再執行,那麼select將會繼續向下執行下一個case,在下一個case中,有一個管道的接收操作x := <- ch,在這裡管道裡有之前第一次迴圈的時候放入的0這個資料,那麼在這裡就會將管道的資料賦值給x,從而列印出第一個資料0,那麼後面的資料就和之前的過程是一樣的了。

看到這裡,大概就能明白select的作用了,順便說一下,select的case語句中,都是對應一個I/O操作,準確的說是對應一個channel的I/O操作,那麼到這裡也應該可以理解為什麼在code-1中,一個無緩衝的channel能在那段代碼中產生一個deadlock

這裡還引出幾個概念:channel, buffer channel, goroutine等。

OK!今天就先到這裡,下次再繼續分享Golang的特色之一,goroutine

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.