亚洲区国产区激情区无码区,国产成人mv视频在线观看,国产A毛片AAAAAA,亚洲精品国产首次亮相在线

Golang 菜鳥教程

Golang 控制語句

Golang 函數(shù) & 方法

Golang 結(jié)構(gòu)體

Golang 切片 & 數(shù)組

Golang 字符串(String)

Golang 指針

Golang 接口

Golang 并發(fā)

Golang 異常(Error)

Golang 其他雜項

Go 語言通道(Channel)

在Go語言中,通道是goroutine與另一個goroutine通信的媒介,并且這種通信是無鎖的。換句話說,通道是一種技術(shù),它允許一個goroutine將數(shù)據(jù)發(fā)送到另一個goroutine。默認(rèn)情況下,通道是雙向的,這意味著goroutine可以通過同一通道發(fā)送或接收數(shù)據(jù),如下圖所示:

創(chuàng)建通道

在Go語言中,使用chan關(guān)鍵字創(chuàng)建通道,并且該通道只能傳輸相同類型的數(shù)據(jù),不允許從同一通道傳輸不同類型的數(shù)據(jù)。

語法:

var Channel_name chan Type

您還可以使用簡寫聲明通過make()函數(shù)創(chuàng)建通道。

語法:

channel_name:= make(chan Type)
package main

import "fmt"

func main() {

    //使用var關(guān)鍵字創(chuàng)建通道
    var mychannel chan int
    fmt.Println("channel的值: ", mychannel)
    fmt.Printf("channel的類型: %T ", mychannel)

    // 使用 make() 函數(shù)創(chuàng)建通道
    mychannel1 := make(chan int)
    fmt.Println("\nchannel1的值:", mychannel1)
    fmt.Printf("channel1的類型: %T ", mychannel1)
}

輸出:

channel的值:  <nil>
channel的類型: chan int
channel1的值: 0xc0000160c0
channel1的類型: chan int

從通道發(fā)送和接收數(shù)據(jù)

在Go語言中,通道工作有兩個主要的操作,一個是發(fā)送,另一個是接收,這兩個操作統(tǒng)稱為通信。<-運(yùn)算符的方向表示是接收數(shù)據(jù)還是發(fā)送數(shù)據(jù)。在通道中,默認(rèn)情況下,發(fā)送和接收操作塊直到另一端沒有數(shù)據(jù)為止。它允許goroutine在沒有顯式鎖或條件變量的情況下彼此同步。

  1. 發(fā)送操作:發(fā)送操作用于在通道的幫助下將數(shù)據(jù)從一個goroutine發(fā)送到另一個goroutine。像int,float64和bool之類的值可以安全且容易地通過通道發(fā)送,因?yàn)樗鼈兪潜粡?fù)制的,因此不存在意外并發(fā)訪問相同值的風(fēng)險。同樣,字符串也是安全的,因?yàn)樗鼈兪遣豢勺兊?。但是,通過通道發(fā)送指針或引用(例如切片,map集合等)并不安全,因?yàn)橹羔樆蛞玫闹悼赡軙ㄟ^同時發(fā)送goroutine或接收goroutine更改,并且結(jié)果無法預(yù)測。因此,在通道中使用指針或引用時,必須確保它們一次只能由一個goroutine訪問。

    Mychannel <- element

    上面的語句表明數(shù)據(jù)(element)在<-運(yùn)算符的幫助下發(fā)送到通道(Mychannel)。

  2. 接收操作:接收操作用于接收發(fā)送操作方發(fā)送的數(shù)據(jù)。

    element := <-Mychannel

    上面的語句表明該元素從channel(Mychannel)接收數(shù)據(jù)。如果接收到的語句的結(jié)果不可用(不需要使用),則也是有效的語句。您還可以編寫如下的receive語句:

    <-Mychannel
package main 
  
import "fmt"
  
func myfunc(ch chan int) { 
  
    fmt.Println(234 + <-ch) 
} 
func main() { 
    fmt.Println("主方法開始") 
    //創(chuàng)建通道l 
    ch := make(chan int) 
  
    go myfunc(ch) 
    ch <- 23 
    fmt.Println("主方法結(jié)束") 
}

輸出:

主方法開始
257
主方法結(jié)束

關(guān)閉通道

您也可以在close()函數(shù)的幫助下關(guān)閉通道。這是一個內(nèi)置函數(shù),并設(shè)置一個標(biāo)識,表示不再有任何值將發(fā)送到該通道。

語法:

close()

您也可以使用for范圍循環(huán)關(guān)閉通道。在這里,接收器goroutine可以借助給定的語法檢查通道是打開還是關(guān)閉:

ele, ok:= <- Mychannel

在此,如果ok的值為true,則表示通道已打開,因此可以執(zhí)行讀取操作。并且,如果的值為false,則表示該通道已關(guān)閉,因此將不執(zhí)行讀取操作。

//Go程序說明如何
//關(guān)閉使用的通道
//range循環(huán)和關(guān)閉函數(shù)
package main

import "fmt"

func myfun(mychnl chan string) {

    for v := 0; v < 4; v++ {
        mychnl <- "nhooo"
    }
    close(mychnl)
}

func main() {

    //創(chuàng)建通道
    c := make(chan string)

    // 使用 Goroutine
    go myfun(c)

    //當(dāng)ok的值為為true時,表示通道已打開,可以發(fā)送或接收數(shù)據(jù)
    //當(dāng)ok的值設(shè)置為false時,表示通道已關(guān)閉
    for {
        res, ok := <-c
        if ok == false {
            fmt.Println("通道關(guān)閉 ", ok)
            break
        }
        fmt.Println("通道打開 ", res, ok)
    }
}

輸出:

通道打開  nhooo true
通道打開  nhooo true
通道打開  nhooo true
通道打開  nhooo true
通道關(guān)閉  false

重要注意事項

  • 阻止發(fā)送和接收:在通道中,當(dāng)數(shù)據(jù)發(fā)送到通道時,控制在發(fā)送語句中被阻塞,直到其他goroutine從該通道讀取數(shù)據(jù)。類似地,當(dāng)通道從goroutine接收數(shù)據(jù)時,read語句塊直到另一條goroutine語句。

  • 零值通道:通道的零值為nil。

  • 通道中的For循環(huán): for循環(huán)可以遍歷通道上發(fā)送的順序值,直到關(guān)閉為止。

    語法:

    for item := range Chnl { 
         // 語句..
    }
    package main 
    import "fmt"
      
    func main() { 
      
        // 使用 make() 函數(shù)創(chuàng)建通道
        mychnl := make(chan string) 
      
        // 匿名 goroutine 
        go func() { 
            mychnl <- "GFG"
            mychnl <- "gfg"
            mychnl <- "Geeks"
            mychnl <- "nhooo"
            close(mychnl) 
        }() 
      
        //使用for循環(huán)
        for res := range mychnl { 
            fmt.Println(res) 
        } 
    }

    輸出:

    GFG
    gfg
    Geeks
    nhooo
  • 通道的長度:在通道中,您可以使用len()函數(shù)找到通道的長度。在此,長度表示在通道緩沖區(qū)中排隊的值的數(shù)量。

    package main 
      
    import "fmt"
    
    func main() { 
      
        // 使用 make() 函數(shù)創(chuàng)建通道 
        mychnl := make(chan string, 4) 
        mychnl <- "GFG"
        mychnl <- "gfg"
        mychnl <- "Geeks"
        mychnl <- "nhooo"
    
        // 使用  len() 函數(shù)查找通道的長度 
        fmt.Println("channel長度為: ", len(mychnl)) 
    }

    輸出:

    channel長度為:  4
  • 通道的容量:在通道中,您可以使用cap()函數(shù)找到通道的容量。在此,容量表示緩沖區(qū)的大小。

    package main
    
    import "fmt"
    
    func main() {
    
        // 使用 make() 函數(shù)創(chuàng)建通道
        mychnl := make(chan string, 4)
        mychnl <- "GFG"
        mychnl <- "gfg"
        mychnl <- "Geeks"
        mychnl <- "nhooo"
    
        // 使用  cap() 函數(shù)查找通道的容量
        fmt.Println("channel容量為: ", cap(mychnl))
    }

    輸出:

    channel容量為:  5
  • Channel中的Select和case語句:在go語言中,select語句就像沒有任何輸入?yún)?shù)的switch語句。在通道中使用select語句從case塊提供的多個操作中執(zhí)行單個操作。