Go笔记day3 | 青训营

100 阅读6分钟

select

好的,下面是针对 select 和函数的详细笔记:

1. select语句

select 是 Go 语言中用于处理异步 I/O 操作和并发控制的关键字。它用于同时监听多个通道的操作,并在其中任何一个通道就绪时触发相应的动作。

select 语句由多个 case 子句组成,每个子句表示一个对通道的操作(发送或接收)。当某个通道的读写操作变为非阻塞状态时,对应的 case 子句将被执行。

  • select 语句的执行方式是非确定性的,即无法预测哪个子句会被执行。
  • 如果多个 case 子句同时满足条件,Go 语言会随机选择其中一个来执行。
  • 可以使用 default 关键字指定默认操作,当没有任何通道操作就绪时,执行 default 子句。

select 语句常用于以下场景:

  • 监听多个通道的数据,并做出相应的处理。
  • 实现超时控制,当特定时间内没有通道操作就绪时,执行超时逻辑。
  • 控制并发任务的执行,根据通道的情况触发不同的操作。

2. 函数

在 Go 语言中,函数是一种可重复使用的代码块,用于封装一系列操作并实现特定功能。函数是编程语言中最基本的组成单元,它具有以下特点:

  • 函数由函数名、参数列表、返回值列表和函数体组成。

  • 函数名用于标识函数并在其他代码中进行调用。

  • 参数列表是函数的输入值,可以包含多个参数,每个参数都有自己的类型和名称。

  • 返回值列表是函数的输出结果,可以包含多个返回值,每个返回值都有自己的类型。

  • 函数体包含了具体的执行逻辑,用于实现函数的功能。

  • add 是函数的名字。

  • ab 是两个参数,类型都为 int

  • int 是返回值类型,表示函数返回一个整数值。

  • 函数体中的 return 语句用于返回计算结果。

  • 使用函数名和参数列表进行调用,并将返回的结果赋值给变量 sum

  • 最终输出变量 sum 的值为 8。

在 Go 语言中,函数还有其他一些特性和用法,例如支持多返回值、支持匿名函数、支持可变参数等。函数在模块化设计和代码复用方面起到了关键作用,是学习和掌握的重要部分。

希望这份笔记对您有所帮助!如果您还有其他问题,请随时提问。

select是Go中的一个控制结构,很像linux环境下c开发中的select,都是用来处理异步IO操作,用来处理网络客户端异步的连接应该也是可以的,类似于switch语句,用于处理异步IO操作。select会监听case语句中channel的读写操作,当case中channel读写操作为非阻塞状态(即能读写)时,将会触发相应的动作。 select中的case语句必须是一个channel操作。

eg

func main() {
	var c1, c2, c3 chan int
	var i1, i2 int
	select { //每个case语句中必须是IO操作
	case i1 = <-c1:
		fmt.Print("receive", i1, "from c1\n")
	case c2 <- i2:
		fmt.Print("sent", i2, "to c2\n")
	case i3, ok := <-c3:
		if ok {
			fmt.Print("received", i3, "from c3\n")
		} else {
			fmt.Print("c3 is closed\n")
		}
	default:
		fmt.Printf("no communication\n")
	}
}

可以执行的选择任意一句进行执行,如果都不能执行且没有default那么就进行IO阻塞,相当于是一个监听IO操作的选择语句 --select

判定超时操作

func main() {
	var ch = make(chan int)
	select {
	case data := <-ch:
		dodata(data)
	case <-time.After(time.Second * 3):
		fmt.Println("time out")
	}
}

func dodata(data int) {

}

当然,下面是针对 Go 语言中的通道(Channels)的详细笔记:

1. 通道(Channels)

通道是一种用于在 Goroutine 之间进行通信和同步的机制。它可以让不同的 Goroutine 安全地发送和接收数据,实现协调并发操作。

通道可以被看作是一个队列,支持先进先出(FIFO)的数据结构。通过使用通道,Goroutine 可以安全地发送数据到通道或从通道接收数据。

2. 通道的声明和初始化

通道的声明和初始化可以使用如下的语法:

var 变量名 chan 数据类型
变量名 = make(chan 数据类型)

其中,变量名 是通道的名称,数据类型 是通道中传输的数据类型。

通道的初始化需要使用内置函数 make(),通过 make(chan 数据类型) 创建一个通道对象。

示例:

var ch chan int
ch = make(chan int)

这样就创建了一个名为 ch 的整型通道。

另外,还可以使用短变量声明来简化通道的声明和初始化:

ch := make(chan int)

这样就创建了一个名为 ch 的整型通道。

3. 通道的发送和接收

通过使用 <- 操作符,可以在通道上发送和接收数据。

发送数据到通道的语法为:通道 <- 值

ch <- 10 // 将值 10 发送到通道 ch

从通道接收数据的语法为:变量 = <- 通道

x := <- ch // 从通道 ch 接收值,并赋值给变量 x

发送和接收操作都是阻塞的,即程序在发送或接收数据时,如果没有 Goroutine 准备好进行相应的操作,将会阻塞当前 Goroutine 的执行。

4. 关闭通道

通过内置函数 close() 可以显式地关闭通道。关闭通道后,仍然可以从通道接收已发送的数据,但不能再向通道发送数据。

关闭通道的语法为:close(通道)

close(ch) // 关闭通道 ch

可以使用带有第二个返回值的接收表达式来判断通道是否已经被关闭:

data, ok := <-ch
if !ok {
    // 通道已关闭
}

5. 通道的特性

  • 通道是类型安全的,即只能发送和接收相同类型的数据。
  • 通道的默认值为 nil,需要通过 make() 初始化后才能使用。
  • 通道可以用作函数参数或返回值,用于实现函数间的数据传递。
  • 通道可以设置缓冲区大小,通过 make(chan 数据类型, 缓冲区大小) 初始化。缓冲区允许在发送操作之后,发送方不立即阻塞,而是在缓冲区满之前继续执行。
  • 可以使用 select 语句来实现多路复用,同时监听多个通道的操作。

希望这份笔记对您有所帮助!如果您还有其他问题,请随时提问。