golang中make 和 new 的区别

简介: golang中make 和 new 的区别

golang中make 和 new 的区别


介绍


new


  • new 是一个内建函数,用于分配一块内存并返回指向该内存的指针。
  • 它会为该类型的零值分配内存,并返回指向该类型的指针。
package main

import (
  "fmt"
)

// 定义一个结构体
type Person struct {
  Name string
  Age  int
}

func main() {
  // 使用 new 内建函数创建一个 *Person 类型的指针,并将其赋值给 p
  p := new(Person)

  // 因为 new 分配了内存,所以 p 不会是 nil
  if p == nil {
    fmt.Println("p is nil.")
  } else {
    fmt.Println("p is not nil.")
  }

  // 访问结构体字段并设置值
  p.Name = "Alice"
  p.Age = 30

  // 输出结构体字段的值
  fmt.Println("Name:", p.Name)
  fmt.Println("Age:", p.Age)
}
  • 运行结果


make


  • make 也是一个内建函数,主要用于创建切片、映射和通道等引用类型的数据结构。
  • make 只能用于切片、映射和通道的创建,不适用于其他类型。
package main

import (
  "fmt"
)

func main() {
  // 使用 make 创建一个切片,长度为 3,容量为 5
  slice := make([]int, 3, 5)

  // 添加元素到切片中
  slice[0] = 1
  slice[1] = 2
  slice[2] = 3

  // 输出切片的长度和容量
  fmt.Println("Length of slice:", len(slice))
  fmt.Println("Capacity of slice:", cap(slice))

  // 使用 make 创建一个映射
  m := make(map[string]int)

  // 添加键值对到映射中
  m["apple"] = 10
  m["banana"] = 20

  // 输出映射的内容
  fmt.Println("Map m:", m)

  // 使用 make 创建一个通道
  ch := make(chan int)

  // 在 goroutine 中发送数据到通道
  go func() {
    ch <- 42
  }()

  // 从通道中接收数据
  value := <-ch
  fmt.Println("Value received from channel:", value)
}

  • 运行结果


区别


  1. 适用类型:
  • new 适用于任何类型,但返回的是该类型的指针。
  • make 仅适用于切片、映射和通道的创建,返回的是对应引用类型的实例。
  1. 返回类型:
  • new 返回的是指向类型的指针。
  • make 返回的是对应引用类型的实例,而不是指针。
  1. 初始化:
  • new 分配的内存会被清零,返回的是该类型的零值的指针。
  • make 返回的是被初始化过的引用类型的实例,如切片、映射和通道等。


代码示例


下面是用 Go 语言演示 make 和 new 的区别的代码:

package main

import (
    "fmt"
)

func main() {
    // 使用 new 分配内存
    var p *int
    p = new(int)
    fmt.Println("*p:", *p) // 输出:*p: 0

    // 使用 make 创建切片
    slice := make([]int, 5)
    fmt.Println("slice:", slice) // 输出:slice: [0 0 0 0 0]

    // 使用 make 创建映射
    m := make(map[string]int)
    m["a"] = 1
    fmt.Println("map:", m) // 输出:map: map[a:1]

    // 使用 new 创建结构体指针
    type Person struct {
        Name string
        Age  int
    }
    personPtr := new(Person)
    fmt.Println("personPtr:", personPtr) // 输出:personPtr: &{ 0}

    // 使用 make 创建通道
    ch := make(chan int)
    fmt.Println("channel:", ch) // 输出:channel: 0xc0000180c0
}
  • 运行结果·

相关文章
|
7月前
|
Go
golang中置new()函数和make()函数的区别
golang中置new()函数和make()函数的区别
Golang中的New和Make:内存分配与初始化的区别
摘要:本文将深入探讨Golang中的New和Make函数在内存分配和初始化方面的区别。我们将通过理论阐述和示例代码来解释这两个函数的作用,并帮助读者更好地理解它们在实际编程中的应用。
|
3月前
|
Go
Golang语言之管道channel快速入门篇
这篇文章是关于Go语言中管道(channel)的快速入门教程,涵盖了管道的基本使用、有缓冲和无缓冲管道的区别、管道的关闭、遍历、协程和管道的协同工作、单向通道的使用以及select多路复用的详细案例和解释。
121 4
Golang语言之管道channel快速入门篇
|
3月前
|
Go
Golang语言文件操作快速入门篇
这篇文章是关于Go语言文件操作快速入门的教程,涵盖了文件的读取、写入、复制操作以及使用标准库中的ioutil、bufio、os等包进行文件操作的详细案例。
68 4
Golang语言文件操作快速入门篇
|
3月前
|
Go
Golang语言之gRPC程序设计示例
这篇文章是关于Golang语言使用gRPC进行程序设计的详细教程,涵盖了RPC协议的介绍、gRPC环境的搭建、Protocol Buffers的使用、gRPC服务的编写和通信示例。
106 3
Golang语言之gRPC程序设计示例
|
3月前
|
安全 Go
Golang语言goroutine协程并发安全及锁机制
这篇文章是关于Go语言中多协程操作同一数据问题、互斥锁Mutex和读写互斥锁RWMutex的详细介绍及使用案例,涵盖了如何使用这些同步原语来解决并发访问共享资源时的数据安全问题。
89 4
|
3月前
|
Go
Golang语言错误处理机制
这篇文章是关于Golang语言错误处理机制的教程,介绍了使用defer结合recover捕获错误、基于errors.New自定义错误以及使用panic抛出自定义错误的方法。
51 3
|
3月前
|
Go 调度
Golang语言goroutine协程篇
这篇文章是关于Go语言goroutine协程的详细教程,涵盖了并发编程的常见术语、goroutine的创建和调度、使用sync.WaitGroup控制协程退出以及如何通过GOMAXPROCS设置程序并发时占用的CPU逻辑核心数。
55 4
Golang语言goroutine协程篇
|
3月前
|
Prometheus Cloud Native Go
Golang语言之Prometheus的日志模块使用案例
这篇文章是关于如何在Golang语言项目中使用Prometheus的日志模块的案例,包括源代码编写、编译和测试步骤。
59 3
Golang语言之Prometheus的日志模块使用案例
|
3月前
|
Go
Golang语言之函数(func)进阶篇
这篇文章是关于Golang语言中函数高级用法的教程,涵盖了初始化函数、匿名函数、闭包函数、高阶函数、defer关键字以及系统函数的使用和案例。
66 3
Golang语言之函数(func)进阶篇