Golang Make 函数——初始化切片、映射和通道

文章目录

Go 有一个特殊的 make 函数,可用于初始化通道、切片和映射。

使用 make,我们可以指定正在创建的数据类型的内存和容量限制,为我们提供使用常规构造函数无法实现的低级别控制。

基本用法

make 是 Go 中的一个特殊函数,它可以接受不同数量的类型和参数。

它将返回第一个参数指定的类型的实例:

obj := make(someType, optionalArgument1, optionalArgument2)

在这里,someType 可以是切片、映射或通道。

创建切片

我们可以使用 make 初始化任何类型的切片:

words := make([]string, 2)

这里,第一个参数是类型,第二个参数是长度

默认情况下,一个新切片被初始化并填充与指定长度一样多的空值。

因此,在这种情况下,words 的值将是 []string{"", ""}

我们还可以在创建切片时传递第三个参数,即容量。容量表示分配给一个切片的内存量,即使它的长度可能没有那么多。

例如,如果我们也使用容量来创建 words

words := make([]string, 2, 5)

容量参数必须大于长度参数,否则代码将无法构建

words 的值现在仍然是 []string{"", ""},但是底层内存被分配给 5 个字符串值。

len=2 cap=5
|""|""|X|X|X|

因此,如果我们使用 append 添加另一个元素,Go 不会在后台分配更多内存:

words = append(words, "axiaoxin blog")

默认情况下,如果你不分配任何容量,Go 会采用默认容量。添加更多列表元素时,Go 会在需要时提供更多容量。

因此,如果你事先知道切片的大小,那么指定容量就非常有用,因为每次超过默认容量时我们都可以跳过额外的分配。

请注意,指定容量并没有限制最大限制,而是规定了在添加更多元素时需要重新分配的初始容量

创建映射

make 与 maps 一起使用并不像 slice 那样简单。

// make 一个空 map
m := make(map[int]string)

// make 一个 n 个元素的 map
m := make(map[int]string, n)

我们依旧可以 make 空的 map 实例,并指定容量,但是这里的容量是一个语言上的示意,并不对分配的确切容量做出任何保证。

Golang 语言规范提到第二个参数是指“大约 n 个元素的初始空间”

创建通道

我们可以使用 make 创建不同类型的通道:

  1. 无缓冲通道,不能存储任何数据,只能充当数据管道:
    // 创建一个无缓冲的整数通道
    out := make(chan int)
    
  2. 可以存储一定数量数据的缓冲通道
    // 创建一个缓冲通道,最多可以容纳 3 个整数值
    out := make(chan int, 3)
    

make 与 new 的区别

Go 还有一个内置函数 new,它经常出现在与 make 类似的场景中,但具有不同的功能。

make 能够分配变量内存并返回所提供类型的实例,而 new 只能初始化空实例,并返回所提供参数的指针。

让我们看一个例子:

// 返回一个包含 1 个默认 (0) int 元素的切片
s1 := make([]int, 1)
// 返回一个指向空切片的指针
s2 := new([]int)

fmt.Println(s1)
fmt.Println(s2)

如果我们运行这段代码,我们将得到:

[0]
&[]

总结

make 是一个多功能的内置函数,可用于初始化不同的数据类型。

参数及其意义取决于被初始化的变量类型。

可以在Golang语言规范中阅读更多有关 makenew 如何工作的详细信息。


也可以看看


全国大流量卡免费领

19元月租ㆍ超值优惠ㆍ长期套餐ㆍ免费包邮ㆍ官方正品