new() and make() in GoLang

  sonic0002        2023-11-18 13:43:25       1,624        0          English  简体中文  Tiếng Việt 

GoLang 是一种现代的、静态类型的、编译型编程语言,旨在构建可扩展、并发且高效的软件。它提供了各种内置函数和特性,帮助开发人员编写简洁高效的代码。其中包括new()make()函数,乍一看可能很相似,但在 GoLang 中却有着不同的用途,对于内存分配和数据初始化至关重要。

在这篇博文中,我们将探讨new()make()函数之间的区别,并了解何时以及如何有效地使用它们。

new() 和 make()

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

new() 函数

new()用于为值类型(例如整数、浮点数和结构体)分配内存,并返回指向新分配的零值的指针。

它接受一个参数,即类型,并返回指向该类型的指针。

make() 函数

make()用于创建和初始化切片、映射和通道,它们是 GoLang 中的引用类型。

它根据类型接受两个或三个参数,并返回一个已初始化(非零值)的、可立即使用的值。

理解 new() 函数

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

func new(Type) *Type

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

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

package main

import "fmt"

type Person struct {
    Name string
    Age  int
}

func main() {
    // 使用 new() 为 Person 结构体分配内存
    p := new(Person)

    fmt.Printf("%T\n", p)

    // 使用指针访问结构体字段
    p.Name = "Alice"
    p.Age = 30

    // 显示值
    fmt.Println("Name:", p.Name)
    fmt.Println("Age:", p.Age)
}

输出将是

*main.Person
Name: Alice
Age: 30

理解 make() 函数

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

对于切片

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

这是一个使用make()创建切片的例子:

package main

import "fmt"

func main() {
    // 使用 make() 创建一个整数切片
    numbers := make([]int, 5, 10)

    // 显示切片的长度、容量和值
    fmt.Println("Length:", len(numbers))
    fmt.Println("Capacity:", cap(numbers))
    fmt.Println("Values:", numbers)

    // 使用 make() 创建一个整数切片
    numbersWithoutOptional := make([]int, 5)

    // 显示切片的长度、容量和值
    fmt.Println("Length:", len(numbersWithoutOptional))
    fmt.Println("Capacity:", cap(numbersWithoutOptional))
    fmt.Println("Values:", numbersWithoutOptional)
}

输出将是

Length: 5
Capacity: 10
Values: [0 0 0 0 0]
Length: 5
Capacity: 5
Values: [0 0 0 0 0]

对于映射

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

这是一个使用make()创建映射的例子:

package main

import "fmt"

func main() {
    // 使用 make() 创建一个字符串键和整数值的映射
    scores := make(map[string]int)
    // 向映射中添加值
    scores["Alice"] = 95
    scores["Bob"] = 87
    // 显示映射
    fmt.Println("Scores:", scores)
}

输出将是

Scores: map[Alice:95 Bob:87]

对于通道

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

这是一个使用make()创建通道的例子:

package main

import (
    "fmt"
    "time"
)

func main() {
    // 使用 make() 创建一个非缓冲的整数通道
    ch := make(chan int)
    // 使用 goroutine 将数据发送到通道
    go func() {
        for i := 1; i <= 5; i++ {
            ch <- i
            time.Sleep(time.Second) // 模拟发送下一个值之前的一些工作
        }
        close(ch)
    }()
    // 从通道接收数据
    for num := range ch {
        fmt.Println("Received:", num)
    }
}

输出将是

Received: 1
Received: 2
Received: 3
Received: 4
Received: 5

结论

在这篇博文中,我们揭开了 GoLang 中new()make()函数的神秘面纱,并解释了它们的差异和用例。总而言之:

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

理解new()make()之间的区别对于在 GoLang 中进行高效的内存分配和数据初始化至关重要。正确使用这些函数将使您的 GoLang 项目中的代码更简洁和优化。编码愉快!

NEW  GOLANG  MAKE 

       

  RELATED


  0 COMMENT


No comment for this article.



  RANDOM FUN

When new comer tries to refactor code