Golang中make函数的作用及变量初始值解析

Golang中make函数的作用及变量初始值解析 这是一个关于 make 的问题。

在 C++ 语言中,指针变量是存在于栈中的变量,内部指向堆地址,并使用关键字 new 或函数 malloc() 进行分配。这个概念是一样的吗?

附注:非常抱歉在“GO 论坛”上反复提及 C++。我习惯了 C++,所以在接受 Go 语言时有很多困惑。我的英语也不好,所以 C++ 是唯一能解释我想法的方式。恳请理解。

go

    var z []int // 创建变量?
    z = make([]int,0, 5) // 分配???还是引用新的切片对象???

cpp

char * z = nullptr;  // 创建指针变量,z 指向 nullptr
z = new char[5]; // 分配,z 指向这个堆地址(sizeof(char) * 5)

更多关于Golang中make函数的作用及变量初始值解析的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

make 用于切片时,会创建一个对象并为其分配内存空间。 切片的底层引用的是数组。

更多关于Golang中make函数的作用及变量初始值解析的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你不能直接比较这些概念,因为在 C++ 中你创建的是数组,而在 Go 中你拥有的是切片。

尽管切片的实现背后是一个数组,但它们并不相同。在 Go 和 C++ 中,数组都是一段连续预留的内存空间。

Go 中的切片在数组之上添加了一些元数据。它类似于一个结构体,该结构体包含一个指向底层数组的指针、一个描述底层数组当前大小的整数(称为容量)以及切片中实际值的数量。

如果我对快速网络搜索的结果理解正确的话,这与 C++ 中的 std::vector 是相同的概念。

通常,Go 编程语言规范中包含了这些信息:

内置函数 make 接受一个类型 T,该类型必须是切片、映射或通道类型,后面可以跟一个特定于类型的表达式列表。它返回一个类型为 T 的值(而不是 *T)。内存的初始化方式在初始值一节中有描述。

并且

当为变量分配存储空间时(无论是通过声明还是调用 new),或者当创建新值时(无论是通过复合字面量还是调用 make),如果没有提供显式初始化,变量或值将被赋予默认值。该变量或值的每个元素都设置为其类型的零值:布尔类型为 false,数值类型为 0,字符串类型为 "",指针、函数、接口、切片、通道和映射类型为 nil。这种初始化是递归进行的,因此,例如,如果没有指定值,结构体数组的每个元素的字段都将被置为零值。

在Go语言中,make函数用于初始化切片、映射和通道这三种引用类型,它会分配内存并返回已初始化的值,而不是像C++的new那样返回指针。

核心区别:

  1. make返回的是已初始化的类型实例,而不是指针
  2. Go中的切片、映射、通道本身就是引用类型,不需要额外的指针操作
  3. make会进行零值初始化并准备好内部数据结构

你的代码示例解析:

var z []int  // 声明一个切片变量,此时z为nil切片,底层数组未分配
z = make([]int, 0, 5)  // 分配底层数组,长度为0,容量为5

等效的C++理解:

// Go的切片类似于C++的vector
std::vector<int>* z = nullptr;  // var z []int
z = new std::vector<int>();     // make([]int, 0, 5)
z->reserve(5);                  // 容量为5

不同类型使用make的示例:

// 1. 切片 - 长度3,容量5
s := make([]int, 3, 5)
fmt.Println(len(s), cap(s))  // 3, 5

// 2. 映射 - 初始容量10
m := make(map[string]int, 10)
m["key"] = 100

// 3. 通道 - 缓冲区大小5
ch := make(chan int, 5)
ch <- 1

变量初始值:

  • make([]T, len, cap):创建长度为len,容量为cap的切片,元素为类型T的零值
  • make(map[K]V, cap):创建初始容量为cap的映射
  • make(chan T, buf):创建缓冲区大小为buf的通道

new的区别:

// new返回指针
p := new([]int)    // p是*[]int类型,指向nil切片
*p = make([]int, 3) // 需要额外初始化

// make直接返回初始化后的值
s := make([]int, 3) // s是[]int类型,已初始化

在Go中,切片本身包含指向底层数组的指针、长度和容量,使用make会分配底层数组并设置这些字段。

回到顶部