Go语言之make

描述

make函数是Go的内置函数,它的作用是为slice、map或chan初始化并返回引用。make仅仅用于创建slice、map和channel,并返回它们的实例。

语法和参数

函数签名

func make(t Type, size ...IntegerType) Type
名称含义
tslice, map或channel类型。
size整数类型切片,面对不同类型时意义也不同。是否可省略跟创建类型有关。

使用示例

创建slice

make([]Type, len, cap)

cap可以省略。当cap省略时,默认等于len。此外cap >= len >= 0的条件必须成立。例如,创建一个len和cap均为10的int型slice。

package main

import "fmt"

func main() {
	demo := make([]int, 10)
	fmt.Println("demo:", demo)
    // output: demo: [0 0 0 0 0 0 0 0 0 0]
	fmt.Println("len(demo):", len(demo))
    // output: len(demo): 10
	fmt.Println("cap(demo):", cap(demo))
    // output: cap(demo): 10
}

创建map

make(map[keyType] valueType, size)

keyType表示map的key类型,valueType表示map的value类型。size是一个整型参数,表示map的存储能力,该参数可省略。

package main

import "fmt"

func main() {
	demo := make(map[string]int)
	fmt.Println("demo:", demo)
	// output: demo: map[]
}

创建channel

make(chan Type, size)

使用make创建channel,第一个参数是channel类型。size表示缓冲槽大小,是一个可选的大于或等于0的整型参数,默认size = 0。当缓冲槽不为0时,表示通道是一个异步通道。

package main

import "fmt"

func main() {
	demo := make(chan int, 10)
	fmt.Println("demo:", demo)
	// output: demo: map[]
	fmt.Println("len(demo):", len(demo))
	// output: len(demo): 0
	fmt.Println("cap(demo):", cap(demo))
	// output: cap(demo): 10
}

注意事项

make和new的区别

new的作用是初始化一个指向类型的指针(*T)。使用new函数来分配空间,传递给new函数的是一个类型,不是一个值。返回的是指向这个新分配的零值的指针。

make的作用是为slice、map或chan初始化并返回引用(T)。make仅仅用于创建slice、map和channel,并返回它们的实例。

参考

[1] Go make函数

<think>好的,我现在需要回答关于Go语言make函数的作用和使用场景的问题。首先,我得回忆一下自己对make函数的理解。makeGo语言中用于初始化某些内置类型(如切片、映射和通道)的函数,它分配内存并设置适当的初始值。与new函数不同,new只是分配内存并返回指针,而make会进行更复杂的初始化工作。 接下来,我需要确认make的具体使用场景。通常,当创建切片、映射或通道时,必须使用make。例如,创建一个有初始长度和容量的切片,或者指定映射的初始大小,这些情况下都需要用到make。如果不用make而直接声明,可能会导致nil引用,无法直接使用。比如,var m map[string]int 这样声明的映射是nil,不能直接赋值,必须用make初始化后才能操作。 然后,我需要参考用户提供的引用内容,看看是否有相关的信息。引用[2]提到Go是值传递的语言函数参数会生成变量的拷贝,这可能与make创建的类型有关,因为这些类型本身就是引用类型,即使拷贝了变量,底层数据结构可能还是共享的。引用[3]讨论了函数作为参数传递,虽然不直接相关,但可以辅助说明Go中类型初始化的严谨性。引用[4]中的append函数用于切片,而切片的创建通常需要make,这可能是一个关联点。引用[5]提到Go没有宏,但这里可能不太相关。 接下来,我需要整理官方文档中的说明。根据Go官方文档,make函数的作用是为切片、映射或通道分配并初始化一个对象。make的签名根据类型不同而有所变化,例如对于切片是make(T, len, cap),其中cap可以省略,默认等于len。对于映射,make(T, cap)可以指定初始容量,而通道的make需要指定缓冲区大小。 然后,我需要考虑如何用示例说明。比如创建切片时,使用make([]int, 5)会创建一个长度为5,容量为5的切片,元素初始化为零值。而make([]int, 0, 10)则创建一个长度为0,容量10的切片,适合后续用append添加元素。对于映射,make(map[string]int)会初始化一个空的映射,而make(map[string]int, 100)则预先分配空间,提高性能。通道的例子,比如make(chan int)创建一个无缓冲通道,而make(chan int, 5)创建缓冲区大小为5的通道。 另外,需要注意make和new的区别。new返回指针,而make返回初始化后的类型值。比如new([]int)返回一个指向nil切片的指针,而make([]int, 0)返回一个初始化好的切片。 最后,根据用户要求生成相关问题。可能的问题包括make和new的区别,如何正确初始化映射,make在并发编程中的应用,以及不同参数对性能的影响。需要确保问题覆盖使用场景、原理和常见错误。</think>### Go语言中的`make`函数详解 #### 1. `make`函数的作用 `make`函数用于**初始化并分配内存**给Go语言的内置引用类型,包括**切片(slice)、映射(map)和通道(channel)**。与`new`函数不同,`make`不仅分配内存,还会根据类型特性设置初始结构(如切片的长度和容量、映射的哈希表、通道的缓冲区等)[^2]。 #### 2. 核心使用场景 1. **切片(Slice)** - 创建时指定**长度和容量**(容量可省略,默认等于长度)。 - 示例: ```go s1 := make([]int, 5) // 长度=5,容量=5,元素初始化为0 s2 := make([]int, 0, 10) // 长度=0,容量=10,适合动态扩展[^4] ``` 2. **映射(Map)** - 初始化空的映射,或预分配空间以提升性能。 - 示例: ```go m1 := make(map[string]int) // 默认初始化 m2 := make(map[string]int, 100) // 预分配100元素的存储空间 ``` 3. **通道(Channel)** - 创建无缓冲或有缓冲的通道。 - 示例: ```go ch1 := make(chan int) // 无缓冲通道 ch2 := make(chan int, 5) // 缓冲区大小为5 ``` #### 3. 官方文档说明 根据Go官方定义: - `make(T, args)`的返回值类型为`T`(而非`*T`)。 - 对切片:`make([]T, len, cap)`,`cap`可省略。 - 对映射:`make(map[K]V, initialCapacity)`,容量参数可选。 - 对通道:`make(chan T, bufferSize)`,缓冲区大小可选。 #### 4. 与`new`函数的区别 | 特性 | `make` | `new` | |--------------|----------------------------|---------------------| | 返回值类型 | 初始化后的引用类型(T) | 指针(*T) | | 适用类型 | 切片、映射、通道 | 任意类型 | | 初始化行为 | 分配内存并初始化数据结构 | 仅分配零值内存 | | 示例 | `make([]int, 5)` | `new([]int)` | #### 5. 常见错误场景 - **未初始化的映射直接赋值**: ```go var m map[string]int m["key"] = 1 // 运行时panic(映射为nil) ``` 正确做法:使用`make`初始化。 - **切片容量不足导致频繁扩容**: 若已知元素数量,应通过`make`预分配容量以提高性能[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值