一文带你揭秘Go中new()和make()函数的区别和用途

 更新时间:2023年10月11日 09:04:40   作者:技术的游戏  
Go(或 Golang)是一种现代、静态类型、编译型的编程语言,专为构建可扩展、并发和高效的软件而设计,它提供了各种内置的函数和特性,帮助开发人员编写简洁高效的代码,在本博客文章中,我们将探讨 new() 和 make() 函数之间的区别,了解何时以及如何有效地使用它们

Go(或 Golang)是一种现代、静态类型、编译型的编程语言,专为构建可扩展、并发和高效的软件而设计。它提供了各种内置的函数和特性,帮助开发人员编写简洁高效的代码。其中包括 new() 和 make() 函数,这两个函数乍看起来可能相似,但在 Go 中用于不同的目的,对于内存分配和数据初始化至关重要。

new() 和 make() 函数

new() 和 make() 都是 Go 中的内置函数,用于分配内存。然而,它们用于不同的数据类型和场景:

new() 函数:

  • new() 用于为值类型(例如整数、浮点数、结构体)分配内存,并返回指向新分配的零值的指针。
  • 它接受一个参数,即类型,并返回该类型的指针。

make() 函数:

  • make() 用于创建和初始化切片、映射和通道,这些都是 Go 中的引用类型。
  • 它根据类型的不同接受两个或三个参数,并返回一个已初始化(非零值)的值,可以立即使用。

理解 new() 函数

new() 函数的语法非常简单,如下所示:

func new(Type) *Type

这里的 Type 表示我们想要为其分配内存的值的类型。让我们看一个如何使用 new() 的示例。

在这个示例中,我们使用 new() 创建了 Person 结构体的一个新实例,然后使用指针分配值给其字段。

package main
import "fmt"
type Person struct {
    Name string
    Age  int
}
func main() {
    // Using new() to allocate memory for a Person struct
    p := new(Person)
    fmt.Printf("%T\n", p)
    // Accessing struct fields using the pointer
    p.Name = "Alice"
    p.Age = 30
    // Displaying the values
    fmt.Println("Name:", p.Name)
    fmt.Println("Age:", p.Age)
}

这个程序将产生如下所示的输出。

> go run main.go
*main.Person
Name: Alice
Age: 30

理解 make() 函数

make() 函数的语法取决于它所用于的类型。

对于切片(Slices)

func make([]Type, len, cap) []Type
  • Type:切片将保存的元素类型。
  • len:切片的初始长度。
  • cap:切片的容量,这是可选的,并用于指定底层数组的容量。如果未提供,它默认与长度相同。

使用 make() 创建切片的示例:

package main
import "fmt"
func main() {
    // Using make() to create a slice of integers
    numbers := make([]int, 5, 10)
    // Displaying the slice's length, capacity, and values
    fmt.Println("Length:", len(numbers))
    fmt.Println("Capacity:", cap(numbers))
    fmt.Println("Values:", numbers)
    // Using make() to create a slice of integers
    numbersWithoutOptional := make([]int, 5)
    // Displaying the slice's length, capacity, and values
    fmt.Println("Length:", len(numbersWithoutOptional))
    fmt.Println("Capacity:", cap(numbersWithoutOptional))
    fmt.Println("Values:", numbersWithoutOptional)
}

此程序将产生如下输出。

> go run main.go
Length: 5
Capacity: 10
Values: [0 0 0 0 0]
Length: 5
Capacity: 5
Values: [0 0 0 0 0]

对于映射(Maps)

func make(map[KeyType]ValueType, initialCapacity int) map[KeyType]ValueType
  • KeyType:映射中键的类型。
  • ValueType:与键关联的值的类型。
  • initialCapacity:映射的初始容量。这是可选的,但当预先知道元素数量时,可以用于优化性能。

使用 make() 创建映射的示例:

package main
import "fmt"
func main() {
    // Using make() to create a map of string keys and int values
    scores := make(map[string]int)
    // Adding values to the map
    scores["Alice"] = 95
    scores["Bob"] = 87
    // Displaying the map
    fmt.Println("Scores:", scores)
}
> go run main.go
Scores: map[Alice:95 Bob:87]

对于通道(Channels)

func make(chan Type, capacity int) chan Type
  • Type:可以通过通道发送和接收的值的类型。
  • capacity:通道的缓冲区大小。如果设置为0,通道是无缓冲的。

使用 make() 创建通道的示例:

package main
import (
    "fmt"
    "time"
)
func main() {
    // Using make() to create an unbuffered channel of integers
    ch := make(chan int)
    // Sending data into the channel using a goroutine
    go func() {
        for i := 1; i <= 5; i++ {
            ch <- i
            time.Sleep(time.Second) // Simulating some work before sending the next value
        }
        close(ch)
    }()
    // Receiving data from the channel
    for num := range ch {
        fmt.Println("Received:", num)
    }
}
> go run main.go
Received: 1
Received: 2
Received: 3
Received: 4
Received: 5

结论

在本博客文章中,我们解开了 Go 中的 new() 和 make() 函数的谜团,并解释了它们的区别和用途。总结一下:

  • 使用 new() 为值类型分配内存,并获取指向零值的指针。
  • 使用 make() 创建和初始化切片、映射和通道(引用类型),并指定它们的类型和初始容量。

理解 new() 和 make() 之间的区别对于在 Go 中进行高效的内存分配和数据初始化至关重要。正确使用这些函数将在您的 Golang 项目中产生更干净和更优化的代码。

以上就是一文带你揭秘Go中new()和make()函数的区别和用途的详细内容,更多关于Go new()和make()函数的资料请关注脚本之家其它相关文章!

相关文章

  • GoLang string与strings.Builder使用对比详解

    GoLang string与strings.Builder使用对比详解

    这篇文章主要介绍了GoLang string与strings.Builder使用对比,Builder 用于使用 Write 方法有效地构建字符串。它最大限度地减少了内存复制。零值可以使用了。不要复制非零生成器
    2023-03-03
  • Go语言copy()实现切片复制

    Go语言copy()实现切片复制

    本文主要介绍了Go语言copy()实现切片复制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • 详解minio分布式文件存储

    详解minio分布式文件存储

    MinIO 是一款基于 Go 语言的高性能、可扩展、云原生支持、操作简单、开源的分布式对象存储产品,这篇文章主要介绍了minio分布式文件存储,需要的朋友可以参考下
    2023-10-10
  • Go语言中的并发模式你了解了吗

    Go语言中的并发模式你了解了吗

    工作中查看项目代码,发现会存在使用 GO 语言做并发的时候出现各种各样的异常情况,实际上,出现上述的情况,还是因为我们对于 GO 语言的并发模型和涉及的 GO 语言基础不够扎实,所以本文小编就来带大家深入了解下Go语言中的并发模式吧
    2023-08-08
  • 利用Go语言实现轻量级OpenLdap弱密码检测工具

    利用Go语言实现轻量级OpenLdap弱密码检测工具

    这篇文章主要为大家详细介绍了如何利用Go语言实现轻量级OpenLdap弱密码检测工具,文中的示例代码讲解详细,感兴趣的小伙伴可以尝试一下
    2022-09-09
  • Go语言的文件操作代码汇总

    Go语言的文件操作代码汇总

    本文给大家汇总介绍了go语言中的文件操作的代码,包括文件的读写,文件的新建打开和删除等,希望对大家学习go语言能够有所帮助
    2018-10-10
  • Golang中println和fmt.Println区别解析

    Golang中println和fmt.Println区别解析

    Golang 中打印数据通常使用 fmt.Println() 方法,也可以使用内置的 println() 方法。这两个方法大家可能都使用过,它们的区别是什么呢?本文给大家详细讲解,感兴趣的朋友跟随小编一起看看吧
    2023-03-03
  • golang实现RPC模块的示例

    golang实现RPC模块的示例

    本文详细介绍了在Go语言中如何实现RPC模块,包括RPC服务端和客户端的构建及代码实现,同时提到了使用JSON-RPC的方法,通过简单的步骤,可以实现跨进程的远程过程调用,感兴趣的可以了解一下
    2024-09-09
  • golang查看CPU使用率与内存的方法详解

    golang查看CPU使用率与内存的方法详解

    这篇文章主要给大家介绍了golang查看CPU使用率与内存的方法,以及拓展介绍源码里//go:指令,文中有详细的代码示例以及图文介绍,需要的朋友可以参考下
    2023-10-10
  • Go项目中正确升级第三方依赖实战指南(使用Go Modules)

    Go项目中正确升级第三方依赖实战指南(使用Go Modules)

    这篇文章主要介绍了Go项目中使用Go Modules正确升级第三方依赖的相关资料,Go Modules是Go语言官方提供的依赖管理工具,通过去中心化设计和内置的版本控制机制,实现了高效、安全的依赖管理,需要的朋友可以参考下
    2026-06-06

最新评论