文档章节

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

就叫程舰
 就叫程舰
发布于 2018/09/03 17:15
字数 1133
阅读 16
收藏 0

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一样。

© 著作权归作者所有

共有 人打赏支持
就叫程舰

就叫程舰

粉丝 115
博文 200
码字总数 142961
作品 0
海淀
程序员
私信 提问
Go语言_通神路之五耀篇(1)

1、Go方法 在灵胎篇博客中讲到函数,函数就是类似与java中的方法,然而go中还有一些升级版的函数,叫方法。 只不过这种方法在方法名前还有一个括号加参数,只不过被称呼为接收者,方法名后面...

木九天
2018/08/22
0
0
【Visual C++】游戏开发笔记二十一 游戏基础物理建模(三) 摩擦力系统模拟

本系列文章由zhmxy555(毛星云)编写,转载请注明出处。 http://blog.csdn.net/zhmxy555/article/details/7555785 作者:毛星云 邮箱: happylifemxy@qq.com 期待着与志同道合的朋友们相互交...

长平狐
2012/11/12
65
0
开篇(2017-11-27)

故事很长,不知从何说起?(主编要催稿了-_-||,前方凑字,重点最后两段) 报考长春工业大学 当时选工大的时候,完全是出于一个目的:就是它离延边大学比较近。从此,便走了一条学霸路(伪学...

TinyDolphin
2017/11/27
0
0
juniper 中国区合作伙伴

1、北京世纪华风科技发展有限公司 联系地址:北京市西城区黄寺大街26号 德胜置业大厦5号楼1009室 邮  编:100011 联系电话:400-007-6660 010-57510399 传 真 : 010-6853 9248 公司网址:w...

杰1992
2017/06/15
0
0
WEB架构师成长之路

一 、你必须学习面向对象的基础知识,如果连这个都忘了,那你的编程之路注定是在做原始初级的重复! 很多程序员都知道类、方法、抽象类、接口等概念,但是为什么要面向对象,好处在哪里,要解...

jerry__sun
2016/07/14
226
0

没有更多内容

加载失败,请刷新页面

加载更多

matlab-线性代数 简单方程组求根(有唯一解) 非齐次线性方程组:常数项不全为零

  matlab : R2018a 64bit     OS : Windows 10 x64 typesetting : Markdown    blog : my.oschina.net/zhichengjiu    gitee : gitee.com/zhichengjiu   code clearclc% 2x+......

志成就
27分钟前
1
0
Ubuntu 时间同步配置备忘

缘起 目前使用的 Ubuntu 18 下经常出现时间错误,查了下是默认读取 NTP 服务器的时候出现了 timeout,几次手工修改后一重启就故态复萌了,至于这个问题应该是怪机房还是 GFW,就不清楚了。 ...

郁也风
48分钟前
0
0
计算最佳线程数

计算出应该用于应用程序的理论最佳线程数有助于我们的程序的性能,应用程序运行时特征主要有CPU密集型工作和主要等待IO两种特征,或者是混合一起。 CPU 任务 threads = number of CPUs + 1 在...

woshixin
今天
3
0
搜索引擎(Solr-索引详解2)

学习目标 1.掌握SolrJ的使用。 2.掌握索引API 3.掌握结构化数据导入DIH SolrJ介绍 SolrJ是什么? Solr提供的用于JAVA应用中访问solr服务API的客户端jar。在我们的应用中引入solrj: <depende...

这很耳东先生
今天
3
0
待整理完--分享如何一个月在阿里云账户多了700元

服务器领券地址

吴伟祥
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部