- 使用
new
初始化:
- 初始化过程:
new
函数会为结构体 A
分配内存,并将其所有字段初始化为零值。对于嵌套的结构体 B
,也会被初始化为零值,其切片字段会被初始化为 nil
。
- 内存布局:
new
分配的内存是连续的,结构体 A
的内存紧接着其嵌套的结构体 B
的内存,切片字段在结构体 B
内存布局中有相应的位置,但因为是 nil
,实际数据部分还未分配。
- 示例代码:
package main
import "fmt"
type B struct {
Slice []int
}
type A struct {
InnerB B
}
func main() {
a := new(A)
fmt.Printf("a.InnerB.Slice: %v (type: %T)\n", a.InnerB.Slice, a.InnerB.Slice)
}
- 使用
make
初始化(注:Go 中没有 Gomake
,猜测这里是 make
用于初始化切片等复合类型):
- 初始化过程:
make
不能直接用于初始化结构体 A
,但可以用于初始化结构体 B
中的切片字段。如果在初始化结构体 A
后手动使用 make
初始化 B
中的切片字段,会为切片分配内存并初始化其容量和长度。
- 内存布局:结构体
A
和 B
依然是连续内存布局,但是通过 make
初始化的切片,其实际数据部分会在堆上另外分配一块连续的内存,结构体 B
中的切片字段会持有指向这块数据内存的指针,以及长度和容量信息。
- 示例代码:
package main
import "fmt"
type B struct {
Slice []int
}
type A struct {
InnerB B
}
func main() {
a := A{}
a.InnerB.Slice = make([]int, 0, 5)
fmt.Printf("a.InnerB.Slice: %v (type: %T, len: %d, cap: %d)\n", a.InnerB.Slice, a.InnerB.Slice, len(a.InnerB.Slice), cap(a.InnerB.Slice))
}