其他分享
首页 > 其他分享> > 8.14GO之条件语句

8.14GO之条件语句

作者:互联网

8.14GO之条件语句

Go语言条件语句

一些大题的和类C语言无异,但是:

相当于Java中的:

    public boolean isEmpty(){
       return size == 0 ? true : false;
  }

Go之条件语句

语句描述
[if 语句] if 语句 由一个布尔表达式后紧跟一个或多个语句组成。
[if...else 语句] if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。
[if 嵌套语句] 你可以在 ifelse if 语句中嵌入一个或多个 ifelse if 语句。
[switch 语句] switch 语句用于基于不同条件执行不同动作。
[select 语句] select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。
Go条件语句之select语句

简单理解:

什么是goroutine

goroutine是Go中最基本的执行单元。

特点:

线程(Thread)

特点:

一个标准线程的组成:

一个线程的特点:

协程(coroutine)

特点:

一个协程的特点:

线程与协程的不同点

好处:

Goroutine--->需要深入了解、实践。目前还不是很明白。

特点:

channel的特点

特点:

和多线程ThreadLocal不一样的地方:

ThreadLocal:

ThreadLocal相当于一个共享的内存区域,供多个线程共享堆的数据。线程只能共享堆的数据,不能共享栈的数据。

Goroutine:

可以说goroutine实现了协程之间的栈的数据的共享。

通信的方法就是使用通道(channel),如下图所示:

goroutine与channel的通信

channel 是一种队列一样的结构。

channel规则的特点:

通道的使用方式
  • 声明通道

  • 创建通道

  • 使用通道发送数据


通道本身需要一个类型进行修饰,就像切片类型需要标识元素类型。通道的元素类型就是在其内部传输的数据类型

声明通道类型格式:
var 通道变量 chan 通道类型

chan 类型的空值是 nil,声明后需要配合 make 后才能使用。

创建通道格式--->通道本身是引用类型,需要使用make进行创建
通道实例 := make(chan 数据类型)

示例:

package main

import (
"expvar"
"fmt"
)

func main() {
ch1 := make(chan int) //创建一个整数类型的通道
ch2 := make(chan interface{}) //创建一个空接口类型的通道, 可以存放任意格式

type Equip struct {
expvar.Var
}

ch2 := make(chan *Equip)
fmt.Println()
}
使用通道发送数据--->操作符:<-

通道发送苏剧的格式:

通道变量 <- 值

示例:

package main

func main() {
ch1 := make(chan int) //创建一个整数类型的通道
ch2 := make(chan interface{}) //创建一个空接口类型的通道, 可以存放任意格式

ch1 <- 1
ch2 <- 3.1415926
ch2 <- "Hello,World!"
}
使用通道接受数据--->操作符:<-

通道接收数据的特征:

概括:

接收数据的四种写法:

  1. 阻塞式接收数据
  2. 非阻塞式接收数据
  3. 接收任意数据,忽略接收的数据
  4. 循环接收

阻塞式接收数据:

data <- ch

执行该语句时将会阻塞,直到接收到数据并赋值给 data 变量。

非阻塞式接收数据:

data, ok <- ch

非阻塞的通道接收方法可能造成高的 CPU 占用,因此使用非常少。如果需要实现接收超时检测,可以配合 select 和计时器 channel 进行

接收任意数据,忽略接收的数据:

<- ch

阻塞接收数据后,忽略从通道返回的数据。执行该语句时将会发生阻塞,直到接收到数据,但接收到的数据会被忽略。

通过通道在 goroutine 间阻塞收发实现并发同步。

使用通道做同步并发的实例:

package main

import "fmt"

func main() {
//构建一个通道
ch := make(chan int)

//开启一个并发匿名函数
go func() {
fmt.Println("start goroutine")

//通过通道通知main的goroutine
ch <- 0
fmt.Println("exit goroutine")
}()

fmt.Println("wait goroutine")

//等待匿名goroutine
<- ch

fmt.Println("all done")
}

可以看到执行顺序:

  1. 先执行main中的构建和通道接收的内容。到<- ch此时goroutine进入阻塞状态

  2. 接着等到go func()当中的goroutine运行向通道ch中添加值

  3. 最后main中收到了值以后解除阻塞状态,往下运行

所以输出顺序是:

wait goroutine
start goroutine
exit goroutine
all done

代码说明:

ch := make(chan int) //构建一个同步用的通道。
go func() //开启一个匿名函数的并发。
ch <- 0 //匿名 goroutine 即将结束时,通过通道通知 main 的 goroutine,这一句会一直阻塞直到 main 的 goroutine 接收为止。
<- ch //开启 goroutine 后,马上通过通道等待匿名 goroutine 结束。

虽然是并发运行但是通过阻塞的方式还是可以实现数据的安全、准确性

循环接收:

借用 for range 语句进行多个元素的接收操作

for data := range ch {
}

特点:

有点类似增强for循环

示例:

package main

import (
"fmt"
"time"
)

func main() {
//构建一个通道
chNo2 := make(chan int)

//开启一个并发匿名函数
go func() {

//for循环,从3->0
for i := 3; i > 0; i-- {
//每次将循环的值发送到main的goroutine中
chNo2 <- i

//每次发送完时等待
time.Sleep(time.Second)
}
}()

//遍历接收通道的数据
for data := range chNo2 {
//打印通道数据
fmt.Println(data)

//当遇到数据0时,退出接收循环
if data == 0 {
break
}
}
}

代码说明:

ch := make(chan int)
//通过 make 生成一个整型元素的通道。
go func() //将匿名函数并发执行。
ch <- i //将 3 到 0 之间的数值依次发送到通道 ch 中。
for data := range ch //使用 for 从通道中接收数据。

本篇内容参考:

Go语言通道(chan)——goroutine之间通信的管道

Go goroutine理解 - SegmentFault 思否

go的并发实现原理在后续学习到以后会深入的记录学习过程。

标签:语句,goroutine,chan,线程,GO,8.14,接收,通道
来源: https://www.cnblogs.com/JunkingBoy/p/15149543.html