首頁 > 軟體

Go語言面試題之select和channel的用法

2022-09-06 18:05:43

select

先說switch...case...

switch...case... 很常用,且很好理解。其作用和if...else...一樣。

區別是switch...case 相比於if...else...能讓我們的程式碼看起來更清晰,更好理解。

再說select...case..

golang 的 select 就是監聽 IO 操作,當 IO 操作發生時,觸發相應的動作。 

所說的IO操作就是對channle的操作:向通道傳送資料,或者從通道中讀取資料。

在執行select語句的時候,執行時系統會自上而下地判斷每個case中的傳送或接收操作是否可以被立即執行

什麼是立即執行呢?

立即執行:意思是當前Goroutine不會因當前操作而被阻塞

select類比switch

select的用法與switch非常類似,由select開始一個新的選擇塊,每個選擇條件由case語句來描述。

與switch語句可以選擇任何可使用相等比較的條件相比,select有比較多的限制,其中最大的一條限制就是每個case語句裡必須是一個IO操作。

確切的說,應該是一個面向channel的IO操作。

經典範例

package main

import "fmt"

func main() {
   ch1 := make(chan int, 1)
   ch1 <- 2
   select {
   case v := <-ch1:
      fmt.Println("取到的資料:", v)
   case ch1 <- 1:
      fmt.Println("寫入資料")
   }
}

執行結果

channel

goroutine和channel作為go語言中最重要的兩個知識點,一定要搞清楚。

大家容易出錯的知識點是以下3點,尤其是最後一點:

1.nil channel代表channel未初始化,向未初始化的channel讀寫資料會造成阻塞

2.關閉(close)未初始化的channel會引起panic。

3.從一個關閉的並且沒有值的通道執行接收操作會得到對應型別的零值,並不會引起panic。

1.從已經關閉並且沒有值的通道中取值

package main

import "fmt"

//從關閉的通道中取值範例:
func main() {
   //宣告範例化通道ch1
   ch1 := make(chan int, 1)
   //關閉通道
   close(ch1)
   select {
   //通通道ch1中取值
   case v := <-ch1:
      fmt.Printf("從ch1中取值:%dn", v)
   default:
      fmt.Println("預設case")
   }
}

執行結果

和我們預想中的一樣,取到了對應的零值:

2.從已經關閉並且有值的通道中取值

我們稍微修改一下上面的程式碼

package main

import "fmt"

//從關閉的通道中取值範例:
func main() {
   //宣告範例化通道ch1
   ch1 := make(chan int, 1)
   //向通道中賦值
   ch1 <- 1
   //關閉通道
   close(ch1)
   //關閉之後取值
   after_close_value := <-ch1
   fmt.Printf("關閉之後取值:%dn", after_close_value) //列印結果:關閉之後取值:1
   select {
   //通通道ch1中取值
   case v := <-ch1:
      fmt.Printf("從ch1中取值:%dn", v) //列印結果:從ch1中取值:0
   default:
      fmt.Println("預設case")
   }
}

執行結果

執行結果和我們預想中的一樣:

  • 通道關閉後,如果通道中仍然有值,還是可以正常取到通道中的值的。
  • 通道關閉後,如果通道中已經沒有值了,再從通道中取值,並不會引起panic,而是會取到對應型別的零值。

一圖勝千言

下面的表格中總結了對不同狀態下的通道執行相應操作的結果。

注意: 對已經關閉的通道再執行 close 也會引發 panic。

總結

本文解析了Go語言中select和channel在面試中可能遇到的進階知識點。

到此這篇關於Go語言面試題之select和channel的用法的文章就介紹到這了,更多相關Go select channel內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com