
如上所述,Go 语言提供了多种内存分配和值初始化的方式,包括 &T{...}、&someLocalVar、new 和 make。理解 new 和 make 的区别,有助于更有效地利用 Go 语言的特性。
new 函数用于分配指定类型的新空间,并将其初始化为零值。它返回的是指向该类型零值的指针。例如:
package main
import "fmt"
type Point struct {
X, Y int
}
func main() {
p := new(Point)
fmt.Println(p) // Output: &{0 0}
i := new(int)
fmt.Println(*i) // Output: 0
}在上面的例子中,new(Point) 分配了一个 Point 类型的内存空间,并将其 X 和 Y 字段初始化为零值。new(int) 则分配了一个 int 类型的内存空间,并将其初始化为 0。
需要注意的是,new 只能分配基本类型和结构体的内存,不能用于分配切片、映射和通道的内存。尝试对 int 类型使用取地址符 & 是非法的,例如 &int。
make 函数专门用于创建切片、映射和通道。与 new 不同,make 返回的是这些类型的实例,而不是指针。例如:
package main
import "fmt"
func main() {
// 创建一个长度为 0,容量为 10 的 int 类型切片
s := make([]int, 0, 10)
fmt.Println(s) // Output: []
// 创建一个空的 string 类型的映射
m := make(map[string]string)
fmt.Println(m) // Output: map[]
// 创建一个 int 类型的通道
c := make(chan int)
fmt.Println(c) // Output: 0x... (通道的地址)
close(c) // 关闭通道,防止资源泄露
}在上面的例子中,make([]int, 0, 10) 创建了一个长度为 0,容量为 10 的 int 类型切片。make(map[string]string) 创建了一个空的 string 类型的映射。make(chan int) 创建了一个 int 类型的通道。
| 特性 | new | make |
|---|---|---|
| 作用 | 分配内存,初始化为零值,返回指针 | 创建切片、映射、通道,返回实例 |
| 类型 | 基本类型、结构体 | 切片、映射、通道 |
| 返回值 | 指针 | 实例 |
理论上,可以将 new 和 make 合并为一个内置函数,例如 NEW,但这样做可能会导致更多的混淆。例如:
// 假设存在一个名为 NEW 的函数 // p := NEW(*chan int) // * 是必须的 // c := NEW(chan int) // new(int) --> NEW(*int) // new(Point) --> NEW(*Point) // new(chan int) --> NEW(*chan int) // make([]int, 10) --> NEW([]int, 10) // make(Point) // 非法 // make(int) // 非法
如果只有一个 NEW 函数,则需要使用 * 来区分指针类型,这可能会增加新手的学习成本。因此,Go 语言选择保留 new 和 make 两个独立的内置函数,以提供更清晰和易于理解的内存分配和初始化方式。
总而言之,new 用于基本类型和结构体的内存分配和零值初始化,返回指针;make 专门用于切片、映射和通道的创建,返回实例。理解它们的区别和使用场景,可以帮助你编写更高效、更易于维护的 Go 代码。
以上就是Go 语言中 new 和 make 的选择:内存分配与初始化详解的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号