一、make
make函数是Go的内置函数,它的作用是为slice、map或chan初始化并返回引用。
make仅仅用于创建slice、map和channel,并返回它们的实例。
主要看make和new的区别:
func new(Type) *Type
func make(t Type, size ...IntegerType) Type
1、返回值
从定义中可以看出,new返回的是指向Type的指针。 make直接返回的是Type类型值。
2、参数
new只有一个Type参数,Type可以是任意类型数据。 make可以有多个参数,其中第一个参数与new的参数相同,但是只能是slice,map,或者chan中的一种。对于不同类型,size参数说明如下:
- 对于slice,第一个size表示长度,第二个size表示容量,且容量不能小于长度。如果省略第二个size,默认容量等于长度。
- 对于map,会根据size大小分配资源,以足够存储size个元素。如果省略size,会默认分配一个小的起始size。
- 对于chan,size表示缓冲区容量。如果省略size,channel为无缓冲channel。
二、channel
channel用于goroutines之间的通信,让它们之间可以进行数据交换。像管道一样,一个goroutine_A向channel_A中放数据,另一个goroutine_B从channel_A取数据。
channel是指针类型的数据类型,通过make来分配内存。例如:
ch := make(chan int)
这表示创建一个channel,这个channel中只能保存int类型的数据。也就是说一端只能向此channel中放进int类型的值,另一端只能从此channel中读出int类型的值。
向ch这个channel放数据的操作形式为:
ch <- VALUE
从ch这个channel读数据的操作形式为:
<-ch // 从ch中读取一个值 val = <-ch val := <-ch // 从ch中读取一个值并保存到val变量中 val,ok = <-ch // 从ch读取一个值,判断是否读取成功,如果成功则保存到val变量中
其实很简单,当ch出现在<-
的左边表示send,当ch出现在<-
的右边表示recv。
案例:
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan string)
go sender(ch) // sender goroutine
go recver(ch) // recver goroutine
time.Sleep(1e9)
}
func sender(ch chan string) {
ch <- "malongshuai"
ch <- "gaoxiaofang"
ch <- "wugui"
ch <- "tuner"
}
func recver(ch chan string) {
var recv string
for {
recv = <-ch
fmt.Println(recv)
}
}
输出结果:
malongshuai
gaoxiaofang
wugui
tuner