Go语言_通神路五耀篇(3)
為什么80%的碼農都做不了架構師?>>> ??
1、Reader
io?包指定了?io.Reader?接口,它表示從數據流的末尾進行讀取。
Reader接口包含的方法
func (T) Read(b []byte) (n int, err error)Read?用數據填充給定的字節切片并返回填充的字節數和錯誤值。在遇到數據流的結尾時,它會返回一個?io.EOF?錯誤,如下:
package mainimport ("strings""fmt""io" )func main() {//創建字符串mujiutianr:= strings.NewReader("mujiutian!")//創建byte類型的切片,長度為8b:= make([]byte,8)//循環遍歷,直到遇到數據流的結尾時,他會返回一個io.EOF錯誤for {n,err := r.Read(b)fmt.Printf("n= %v err = %v b= %v \n",n,err,b)if err == io.EOF {break}} }結果:
n= 8 err = <nil> b= [109 117 106 105 117 116 105 97] n= 2 err = <nil> b= [110 33 106 105 117 116 105 97] n= 0 err = EOF b= [110 33 106 105 117 116 105 97]第一次讀取了8個字節數【mujiutia】,第二次數據了兩個字節數【n!】,最后0個。
2、go并發,goroutine
package mainimport ("time""fmt" )func say(s string) {for i := 0; i < 5; i++ {time.Sleep(10 * time.Millisecond)fmt.Println(s)} }func main() {go say("osc")say("mujiutian") }結果,這個結果也是隨機的:
mujiutian osc osc mujiutian osc mujiutian osc mujiutian osc mujiutian從隨機的結果也可以看到,這是兩個單獨的線程在執行,不然一個線程的話會有先后順序,有截圖如下:
2、信道chan
2.1?信道是帶有類型的管道,你可以通過它用信道操作符?<-?來發送或者接收值。
2.2 “箭頭”就是數據流的方向。
2.3 和映射與切片一樣,信道在使用前必須創建。
package mainimport "fmt"func sum(s []int, c chan int) {sum := 0for _, v := range s {sum += v}c <- sum // 將和送入 c }func main() {s := []int{8, 2, 8, -9, 4, 0}c := make(chan int)d := make(chan int)go sum(s[:len(s)/2], c)go sum(s[len(s)/2:], d)x, y := <-d, <-c // 從 c 中接收fmt.Println(x, y, x+y) }結果為:-5 18 13
3、帶緩沖的chan,固定長度
僅當信道的緩沖區填滿后,向其發送數據時才會阻塞。當緩沖區為空時,接受方會阻塞。
這句話的意思就是如果發送數據的長度大于接收數據信道的長度,會發生阻塞,同樣,當發送數據為信道時,而它為空,也出現阻塞,簡單理解就是報錯。
import "fmt"func main() {ch := make(chan int, 1)ch <- 1fmt.Println(<-ch) }現在是一個長度的信道,結果為:1
現在變成兩個,發送數據大于信道長度,如下:
package mainimport "fmt"func main() {ch := make(chan int, 1)ch <- 1ch <- 8fmt.Println(<-ch)fmt.Println(<-ch) }結果報錯:
當信道為空時,作為發送數據一方也同樣會報錯,如下:
func main() {ch := make(chan int, 1)fmt.Println(<-ch) }4、range 和 close
發送者可通過?close?關閉一個信道來表示沒有需要發送的值了。接收者可以通過為接收表達式分配第二個參數來測試信道是否被關閉:若沒有值可以接收且信道已被關閉,那么在執行完
v, ok := <-ch之后?ok?會被設置為false,也就是信道關閉的意思。
只有發送者才能關閉信道,而接收者不能。
向一個已經關閉的信道發送數據會引發程序恐慌(panic)信道與文件不同,通常情況下無需關閉它們。只有在必須告訴接收者不再有值需要發送的時候才有必要關閉,例如終止一個?range?循環
package mainimport "fmt"func fibonacci(n int, c chan int) {x, y := 0, 1for i := 0; i < n; i++ {c <- xx, y = y, x+y}close(c) }func main() {c := make(chan int, 10)go fibonacci(cap(c), c)for i := range c {fmt.Println(i)} }5、select語句
?
package mainimport "fmt"func fibonacci(c, quit chan int) {x, y := 0, 1for {select {case c <- x:x, y = y, x+ycase <-quit:fmt.Println("quit")return}} }func main() {c := make(chan int)quit := make(chan int)go func() {for i := 0; i < 10; i++ {fmt.Println(<-c)}quit <- 0}()fibonacci(c, quit) }結果為:
0 1 1 2 3 5 8 13 21 34 quitselect?語句使一個 Go 程可以等待多個通信操作。就是通信線操作,go成后執行。
當?select?中的其它分支都沒有準備好時,default?分支就會執行。和java的switch中的default一樣。
轉載于:https://my.oschina.net/mdxlcj/blog/1941625
總結
以上是生活随笔為你收集整理的Go语言_通神路五耀篇(3)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简事二三 之 http缓存机制
- 下一篇: hexo博客常用插件及教程