首頁  >  文章  >  web前端  >  Go元素的關鍵字所在--chan頻道

Go元素的關鍵字所在--chan頻道

坏嘻嘻
坏嘻嘻原創
2018-09-14 10:24:082072瀏覽

HTML validate是指HTML驗證。它是透過與標準HTML規則進行比較的方式,分析HTML文件、標記出錯誤和非標準程式碼的處理過程。 Web頁面使用HTML進行渲染,而HTML本身採用了HTML規範作為其規則和標準。透過驗證HTML程式碼穿越多重瀏覽器標準!

chan

chan又稱之為通道,形式類似於管道,內容從一頭被送進去,從另一頭被讀取出來。下邊來介紹定義通道的方法:

var 变量名 chan dataType

定義通道時,需要指定資料類型,就是只允許這個指定資料類型的變數通過這個通道。

初始化通道

golang中在初始化通道類型變數時,可以將通道分為兩種情況,一種是帶緩衝的通道,另一種是不含緩衝的通道。
下邊來介紹下兩種情況的初始化方法:

// 初始化不带缓冲的通道,通道中数据类型是intvar ch1 = make(chan int)// 初始化带10个缓冲的通道,通道中数据类型是stringvar ch2 = make(chan string,10)

還有一種寫法是,定義並初始化通道,

// 定义通道,并给通道初始化8个缓冲ch3 := make(chan int ,8)// 定义通道,并初始化为不带缓冲通道ch4 := make(chan string)

通道賦值

對通道的讀取和寫入都可能進入阻塞狀態。

  1. 沒有緩衝的通道,寫入時,就會發生阻塞,直到通道中資訊讀取後,才會結束阻塞。

  2. 帶緩衝的通道,每次向通道中寫入一次訊息,通道長度就會加1,每成功從通道讀取一次訊息,通道長度會減少1。如果通道長度等於通道緩衝長度時,向通道繼續寫入資訊會使程式阻塞;如果通道長度小於通道緩衝長度,則向通道中寫入資訊不會造成阻塞。假如通道長度是5,那麼在通道沒有被讀取的情況下,向通道中第6次寫入資訊時才會導致程式阻塞。

通道寫入的語法格式是:

var ch = make(chan string,10)// 将字符串”hello"写入到通道中,通道长度加1ch <- "hello"

#讀取通道

通道為空
 1. 頻道沒有關閉,程式會進入阻塞狀態,等到頻道有訊息寫入
 2. 通道已經關閉,不會阻塞,返回通道中資料類型初始值(髒資料),如通道是chan int時,回傳值是0,通道是chan string時,回傳值是空。
 頻道不為空
 1. 頻道沒有關閉,從頻道讀取一次訊息,讀取完成後,往下執行
2. 通道已關閉,從通道中讀取一次信信,讀取完成後,往下執行

#讀取通道操作:

val,ok := <-ch

使用斷言讀取通道中的值,檢查通道是否還有內容,以及判斷通道是否已經關閉,當通道中沒有信息,且通道已經關閉時,ok值為false,當通道沒有關閉,但是通道中沒有信息,程序將會阻塞,如果通道中有內容,則ok值是true。

另一種不使用斷言的方式讀取通道

val := <-ch

寫入與讀取通道

讀取不帶緩衝的通道範例方法:

package mainimport (    "fmt")func main() {    // 定义一个不带缓冲的通道,通道中数据类型是int
    var c = make(chan int)    // 开启一个携程,读取通道中的内容
    go func() {
        fmt.Println("写入信息是:", <-c)
    }()    // 向通道中写入数据
    c <- 1}

輸出結果:

写入信息是: 1

當對帶緩衝的通道進行讀寫時,只要通道中資料長度不大於緩衝長度,就不會出現阻塞,但是讀取帶緩衝的通道,通道中沒有內容時,程式依然會進入阻塞狀態。所以,有緩衝的通道,只對寫入產生影響。下邊來一個範例:

package mainimport (    "fmt")func main() {    var c = make(chan int, 3)
    c <- 1
    c <- 2
    c <- 3
    //c <- 4
    fmt.Println("end")
}

輸出資訊是:

end

當向帶3個緩衝的通道中寫入內容時,由於只寫入了3次,通道的長度剛好等於緩衝的長度,程式沒有阻塞,當c <- 4 前邊的註解去掉後,由於沒有程式去讀取這個通道,主程式進入死鎖狀態而導致異常。

協程通訊

通道類型變數的實質上是一個位址,如下邊範例程式碼:

package mainimport (    "fmt")func main() {    var c = make(chan int, 3)
    fmt.Println(c)
}

輸出結果:

0xc042072080

所以,當通道類型變數當做參數傳入函數後,在函數中可以直接對通道中的值進行修改。雖然chan類型變數是一個位址,但是golang不允許使用取值運算元( * )來操作chan類型變數。但如果你先對chan類型變數使用取位址運算子(&),然後再使用取值運算子(*),這種操作方法還是可以正常運作的,但是這意義不大,除非你的目的是在函數呼叫中,重新定義一個chan類型變數取代原來的變數。

chan的這些特性,可以很好的實現協程之間的同步功能。不帶緩衝的通道,是一種零容忍的等待,可以實現強制同步;帶緩衝的通道,是有一定量容忍度的等待,可以實現允許有一定時間差的同步。

簡單的協程間通訊範例:

package mainimport (    "fmt"
    "time")func main() {    var c = make(chan int)    go func() {
        fmt.Println("待命模式:")        // 读取通道时产生阻塞,等待其他协程向通道写入信息
        fmt.Println("命令代码是:", <-c)
    }()    go func() {        // 延时3秒,向通道中写入信息
        time.Sleep(time.Second * 3)
        fmt.Println("发送命令:")
        c <- 8
        close(c)
    }()
    time.Sleep(time.Second * 5)
    fmt.Println("执行完成")
}

#輸出資訊是:

待命模式:
发送命令:
命令代码是: 8
执行完成

  相關推薦:

HTML validate HTML驗證_HTML /Xhtml_網頁製作

HTML技巧彙編_CSS/HTML

以上是Go元素的關鍵字所在--chan頻道的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn