【高級數據類型】- 5.通道類型

Go語言-通道類型

    通道(Channel)是Go語言中一種很是獨特的數據結構。它可用於在不一樣Goroutine之間傳遞類型化的數據,而且是併發安全的。相比之下,咱們以前介紹的那些數據類型都不是併發安全的。這一點須要特別注意。
  
    Goroutine(也稱爲Go程序)能夠被看作是承載可被併發執行的代碼塊的載體。它們由Go語言的運行時系統調度,並依託操做系統線程(又稱內核線程)來併發地執行其中的代碼塊。至於怎樣編寫這樣的代碼塊以及怎樣驅動這樣的代碼塊執行,咱們先按下不表。
  
    通道類型的表示方法很簡單,僅由兩部分組成,以下:緩存

chan T

    在這個類型字面量中,左邊是表明通道類型的關鍵字chan,而右邊則是一個可變的部分,即表明該通道類型容許傳遞的數據的類型(或稱通道的元素類型)。這兩部分之間須要以空格分隔。
  
    與其它的數據類型不一樣,咱們沒法表示一個通道類型的值。所以,咱們也沒法用字面量來爲通道類型的變量賦值。咱們只能經過調用內建函數make來達到目的。make函數可接受兩個參數。第一個參數是表明了將被初始化的值的類型的字面量(好比chan int),而第二個參數則是值的長度。例如,若咱們想要初始化一個長度爲5且元素類型爲int的通道值,則須要這樣寫:安全

make(chan int, 5)

    順便說一句,實際上make函數也能夠被用來初始化切片類型或字典類型的值。數據結構


    確切地說,通道值的長度應該被稱爲其緩存的尺寸。換句話說,它表明着通道值中能夠暫存的數據的個數。注意,暫存在通道值中的數據是先進先出的,即:越早被放入(或稱發送)到通道值的數據會越先被取出(或稱接收)。
    
    下面,咱們聲明一個通道類型的變量,併爲其賦值:併發

ch1 := make(chan string, 5)

    這樣一來,咱們就可使用接收操做符<-向通道值發送數據了。固然,也可使用它從通道值接收數據。例如,若是咱們要向通道ch1發送字符串"value1",那麼應該這樣作:函數

ch1 <- "value1"

    另外一方面,咱們若想從ch1那裏接收字符串,則要這樣:spa

<- ch1

    這時,咱們能夠直接把接收到的字符串賦給一個變量,如:操作系統

value := <- ch1

    與針對字典值的索引表達式同樣,針對通道值的接收操做也能夠有第二個結果值。請看下面的示例:線程

value, ok := <- ch1


    這樣作的目的一樣是爲了消除與零值有關的歧義。這裏的變量ok的值一樣是bool類型的。它表明了通道值的狀態,true表明通道值有效,而false則表明通道值已無效(或稱已關閉)。更深層次的緣由是,若是在接收操做進行以前或過程當中通道值被關閉了,則接收操做會當即結束並返回一個該通道值的元素類型的零值。按照上面的第一種寫法,咱們無從判斷接收到零值的緣由是什麼。不過,有了第二個結果值以後,這種判斷就好作了。
   
    說到關閉通道值,咱們能夠經過調用內建函數close來達到目的,就像這樣:code

close(ch1)

    請注意,對通道值的重複關閉會引起運行時恐慌。這會使程序崩潰。因此必定要避免這種狀況的發生。另外,在通道值有效的前提下,針對它的發送操做會在通道值已滿(其中緩存的數據的個數已等於它的長度)時被阻塞。而向一個已被關閉的通道值發送數據會引起運行時恐慌。另外一方面,針對有效通道值的接收操做會在它已空(其中沒有緩存任何數據)時被阻塞。除此以外,還有幾條與通道的發送和接收操做有關的規則。不過在這裏咱們記住上面這三條就能夠了。
  
  最後,與切片和字典類型相同,通道類型屬於引用類型。它的零值即爲nil索引

相關文章
相關標籤/搜索