• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Go语言_通神路五耀篇(3)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

1、Reader

io 包指定了 io.Reader 接口,它表示从数据流的末尾进行读取。

Reader接口包含的方法

func (T) Read(b []byte) (n int, err error)

Read 用数据填充给定的字节切片并返回填充的字节数和错误值。在遇到数据流的结尾时,它会返回一个 io.EOF 错误,如下:

package main

import (
   "strings"
   "fmt"
   "io"
)

func main()  {
   //创建字符串mujiutian
   r:= strings.NewReader("mujiutian!")
   //创建byte类型的切片,长度为8
   b:= 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 main

import (
   "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 main

import "fmt"

func sum(s []int, c chan int) {
   sum := 0
   for _, 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 <- 1
   fmt.Println(<-ch)
}

现在是一个长度的信道,结果为:1

现在变成两个,发送数据大于信道长度,如下:

package main


import "fmt"

func main() {
   ch := make(chan int, 1)
   ch <- 1
   ch <- 8
   fmt.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 main


import "fmt"


func fibonacci(n int, c chan int) {
   x, y := 0, 1
   for i := 0; i < n; i++ {
      c <- x
      x, 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 main

import "fmt"

func fibonacci(c, quit chan int) {
   x, y := 0, 1
   for {
      select {
      case c <- x:
         x, y = y, x+y
      case <-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
quit

select 语句使一个 Go 程可以等待多个通信操作。就是通信线操作,go成后执行。

当 select 中的其它分支都没有准备好时,default 分支就会执行。和java的switch中的default一样。

转载于:https://my.oschina.net/mdxlcj/blog/1941625


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
goGOPROXY=http://goproxy.io设置发布时间:2022-07-10
下一篇:
Mastering the game of Go with deep neural networks and tree search (AlphaGo)发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap