Golang中的New和Make:内存分配与初始化的区别

简介: 摘要:本文将深入探讨Golang中的New和Make函数在内存分配和初始化方面的区别。我们将通过理论阐述和示例代码来解释这两个函数的作用,并帮助读者更好地理解它们在实际编程中的应用。

摘要:本文将深入探讨Golang中的NewMake函数在内存分配和初始化方面的区别。我们将通过理论阐述和示例代码来解释这两个函数的作用,并帮助读者更好地理解它们在实际编程中的应用。


一、引言

在Golang中,NewMake是用于内存分配和初始化的重要函数。虽然它们都涉及到内存的分配,但在对象创建和初始化方面存在一些差异。了解这些差异有助于我们更好地选择合适的函数来满足不同的需求。


二、理论背景

1. New函数

New函数用于分配内存并返回一个指向该内存的指针。它接受一个参数类型作为参数,并返回一个指向该类型的零值的指针。这意味着使用New创建的对象会被初始化为其类型的零值。例如,使用Newint将返回一个指向整数的指针,但该整数的值为零。


2. Make函数

相比之下,Make函数用于创建并初始化一个或多个对象。它接受一个类型作为参数,并返回一个已初始化的对象或切片。与New不同,Make会根据类型的初始化规则对对象进行初始化,这意味着它不仅分配内存,还会将内存初始化为类型的非零值。


三、示例代码

为了更好地理解NewMake的差异,让我们通过一些示例代码来深入探讨。

1. New示例

package main
import "fmt"
type Person struct {
    Name string
    Age  int
}
func main() {
    p := New(Person) // 使用New分配内存并返回指向Person类型的零值的指针
    fmt.Println(p)    // 输出:&{ 0}
}


在上面的示例中,我们使用New函数创建了一个指向Person类型的零值的指针。由于Person结构体的字段类型是非零值,因此这些字段的值将为零值(例如,字符串为空字符串,整数为0)。

2. Make示例

package main
import "fmt"
import "container/vector" // 导入vector包以使用Make函数创建向量
func main() {
    v := Make(vector.Vector, 0, 0) // 使用Make创建并初始化一个向量,初始大小为0,容量为0
    fmt.Println(v)               // 输出:[]
}

在上面的示例中,我们使用Make函数创建并初始化了一个向量。由于向量的初始大小和容量都为0,因此它的值为空向量(即长度为0的向量)。但是,请注意,向量的容量将根据需要动态增长。

四、结论与建议

通过以上理论阐述和示例代码,我们可以得出以下结论:


New函数用于分配内存并返回指向类型的零值的指针。这意味着使用New创建的对象会被初始化为类型的零值。在需要创建具有默认值的对象时,可以使用New。例如,对于整数类型,使用Newint将返回一个指向整数的指针,整数的值为零。

Make函数用于创建并初始化一个或多个对象。与New不同,Make会根据类型的初始化规则对对象进行初始化,将其初始化为非零值。因此,当需要创建已经初始化的对象时,可以使用Make。例如,使用Make可以创建一个初始大小和容量为0的向量,但实际使用时向量的大小会动态增长。

在实际编程中,选择使用New还是Make取决于具体的需求。如果只需要创建一个具有默认值的对象,可以使用New;如果需要创建一个已经初始化的对象或切片,可以使用Make。同时,也要注意不同类型的对象或切片的初始化规则,以确保正确使用这两个函数。

五、示例:使用New和Make在实践中

让我们通过一个具体的示例来进一步说明NewMake在实际编程中的应用。

假设我们正在开发一个电子商务网站,需要在购物车中保存用户的商品列表。我们可以使用切片来存储商品,每个商品是一个结构体实例。


首先,我们定义一个Product结构体,表示商品:

type Product struct {
    ID       int
    Name     string
    Price    float64
    Quantity int
}

接下来,我们使用New函数创建一个指向Product类型的零值的指针:

p := New(Product)

然后,我们可以使用该指针创建一个商品对象,并为其字段赋予实际的值:

p.ID = 1
p.Name = "Apple iPhone 13"
p.Price = 999.99
p.Quantity = 1

现在,我们可以将该商品添加到购物车中。购物车可以使用切片来存储商品:

现在,我们可以将该商品添加到购物车中。购物车可以使用切片来存储商品:
cart

然后,我们可以将商品对象添加到购物车中:

cart.PushBack(p) // 将商品添加到购物车中


现在,购物车中有了一个商品。我们可以继续添加更多的商品到购物车中,直到用户结账。

六、总结与建议


在Golang中,New和Make是用于内存分配和初始化的重要函数。New函数用于分配内存并返回指向类型的零值的指针,而Make函数用于创建并初始化一个或多个对象。选择使用哪个函数取决于具体的需求。如果需要创建一个具有默认值的对象,可以使用New;如果需要创建一个已经初始化的对象或切片,可以使用Make。同时,要注意不同类型的对象或切片的初始化规则,以确保正确使用这两个函数。在实际编程中,灵活运用New和Make可以有效地管理内存并提高程序的性能。

相关文章
|
7月前
|
Go
golang中make 和 new 的区别
golang中make 和 new 的区别
55 0
|
7月前
|
存储 算法 关系型数据库
实时计算 Flink版产品使用合集之在Flink Stream API中,可以在任务启动时初始化一些静态的参数并将其存储在内存中吗
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
130 4
|
7月前
|
Go
golang中置new()函数和make()函数的区别
golang中置new()函数和make()函数的区别
|
5月前
|
NoSQL Redis C++
c++开发redis module问题之在复杂的Redis模块中,特别是使用第三方库或C++开发时,接管内存统计有哪些困难
c++开发redis module问题之在复杂的Redis模块中,特别是使用第三方库或C++开发时,接管内存统计有哪些困难
|
6月前
|
存储 编译器 C语言
C语言学习记录——结构体(声明、初始化、自引用、内存对齐、结构体设计、修改默认对齐数、结构体传参)一
C语言学习记录——结构体(声明、初始化、自引用、内存对齐、结构体设计、修改默认对齐数、结构体传参)一
64 2
|
6月前
|
编译器 Linux C语言
C语言学习记录——结构体(声明、初始化、自引用、内存对齐、结构体设计、修改默认对齐数、结构体传参)二
C语言学习记录——结构体(声明、初始化、自引用、内存对齐、结构体设计、修改默认对齐数、结构体传参)二
56 1
|
7月前
|
存储 编译器 Go
Golang深入浅出之-掌握Go语言Map:初始化、增删查改与遍历
【4月更文挑战第21天】Go语言中的`map`提供快速的键值对操作,包括初始化、增删查改和遍历。初始化时,推荐使用`make()`函数,如`make(map[string]int)`。插入和查询键值对直接通过索引访问,更新则重新赋值。删除键值对需用`delete()`函数,确保键存在。遍历map常用`for range`,注意避免在遍历中修改map。了解这些并避免易错点,能提升代码效率和可读性。
127 1
Golang深入浅出之-掌握Go语言Map:初始化、增删查改与遍历
|
7月前
|
Java
SpringBoot 项目启动初始化一个Map对象到内存
SpringBoot 项目启动初始化一个Map对象到内存
155 1
|
25天前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
208 1
|
15天前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。