Go语言学习笔记2

1、接⼝

1)概念:

接⼝是⼀个或多个⽅法签名的集合,任何类型的⽅法集中只要拥有与之对应的全部⽅法,就表⽰它 "实现" 了该接⼝,⽆须在该类型上显式添加接⼝声明。
所谓对应⽅法,是指有相同名称、参数列表 (不包括参数名) 以及返回值。当然,该类型还可以有其他⽅法。
• 接⼝命名习惯以 er 结尾,结构体。
• 接⼝只有⽅法签名,没有实现。
• 接⼝没有数据字段。
• 可在接⼝中嵌⼊其他接⼝。
• 类型可实现多个接⼝。

2)空接口

空接⼝ interface{} 没有任何⽅法签名,也就意味着任何类型都实现了空接⼝。其作⽤类似⾯向对象语⾔中的根对象 object。
 

3)接口执行机制:

接⼝对象由接⼝表 (interface table) 指针和数据指针组成。
 

只有 tab 和 data 都为 nil 时,接⼝才等于 nil。

接⼝表存储元数据信息,包括接⼝类型、动态类型,以及实现接⼝的⽅法指针。

4)接口调用成员变量

2、并发

Go 在语⾔层⾯对并发编程提供⽀持,⼀种类似协程,称作 goroutine 的机制。只需在函数调⽤语句前添加 go 关键字,就可创建并发执⾏单元。开发⼈员⽆需了解任何执⾏细节,调度器会⾃动将其安排到合适的系统线程上执⾏。 goroutine 是⼀种⾮常轻量
级的实现,可在单个进程⾥执⾏成千上万的并发任务。

事实上,⼊⼝函数 main 就以 goroutine 运⾏。另有与之配套的 channel 类型,⽤以实现 "以通讯来共享内存" 的 CSP 模式。CSP(communicating sequential processes)并发模型。——"不要通过共享内存来通信,而应该通过通信来共享内存"

调度器不能保证多个 goroutine 执⾏次序,且进程退出时不会等待它们结束。

1)默认情况下,进程启动后仅允许⼀个系统线程服务于 goroutine。可使⽤环境变量或标准库函数 runtime.GOMAXPROCS 修改,让调度器⽤多个线程实现多核并⾏,⽽不仅仅是并发。

2)调⽤ runtime.Goexit 将⽴即终⽌当前 goroutine 执⾏,调度器确保所有已注册 defer延迟调⽤被执⾏。

3)Gosched 让出底层线程,将当前 goroutine 暂停,放回队列等待下次被调度执⾏。

3、Channel

1)基本应用:
引⽤类型 channel 是 CSP 模式的具体实现,⽤于多个 goroutine 通讯。其内部实现了同步,确保并发安全。默认为同步模式,需要发送和接收配对。否则会被阻塞,直到另⼀⽅准备好后被唤醒。

package main

import "fmt"

func main() {
	data := make(chan int)  // 数据交换队列
	exit := make(chan bool) // 退出通知
	go func() {
		for d := range data { // 从队列迭代接收数据,直到 close 。
			fmt.Println(d)
		}
		fmt.Println("recv over.")
		exit <- true // 发出退出通知。
	}()
	data <- 1 // 发送数据。
	data <- 2
	data <- 3
	close(data) // 关闭队列。
	fmt.Println("send over.")
	<-exit // 等待退出通知。
}

输出:
1 2 3
send over.
recv over.
异步⽅式通过判断缓冲区来决定是否阻塞。如果缓冲区已满,发送被阻塞;缓冲区为空,接收被阻塞。

除⽤ range 外,还可⽤ ok-idiom 模式判断 channel 是否关闭。

向closed channel 发送数据引发 panic 错误,接收⽴即返回零值。⽽ nil channel,⽆论收发都会被阻塞。
内置函数 len 返回未被读取的缓冲元素数量, cap 返回缓冲区⼤⼩。

2)单向channel:

    可以将 channel 隐式转换为单向队列,只收或只发。
3)选择
        如果需要同时处理多个 channel,可使⽤ select 语句。它随机选择⼀个可⽤ channel 做收发操作,或执⾏ default case。在循环中使⽤ select default case 需要⼩⼼,避免形成洪⽔。
4)模式

a、⽤简单⼯⼚模式打包并发任务和 channel。


b、⽤ closed channel 发出退出通知。

c、⽤select 实现超时 (timeout)。



4、⼯作空间

编译⼯具对源码⺫录有严格要求,每个⼯作空间 (workspace) 必须由 bin、 pkg、 src 三个录组成。

5、内存布局


了解对象内存布局,有助于理解值传递、引⽤传递等概念。

猜你喜欢

转载自blog.csdn.net/weixin_42117918/article/details/82500179