go make的使用场景

2025-02-18  本文已影响0人  hehehehe

在 Go 中,make 是一个内置函数,用于创建和初始化以下三种引用类型的数据结构:

  1. 切片(Slice)
  2. 映射(Map)
  3. 通道(Channel)

make 的主要作用是分配内存并初始化这些数据结构,使它们可以正常使用。以下是 make 的使用场景和具体示例。


1. 创建切片(Slice)

场景

语法

make([]T, length, capacity)

示例

package main

import "fmt"

func main() {
    // 创建一个长度为 3,容量为 5 的切片
    s := make([]int, 3, 5)
    fmt.Println(s)             // 输出:[0 0 0],初始值为零值
    fmt.Println(len(s), cap(s)) // 输出:3 5

    // 修改切片元素
    s[0] = 10
    fmt.Println(s)             // 输出:[10 0 0]

    // 动态扩展切片
    s = append(s, 20, 30)
    fmt.Println(s)             // 输出:[10 0 0 20 30]
    fmt.Println(len(s), cap(s)) // 输出:5 5

    // 再次扩展,超过容量,触发扩容
    s = append(s, 40)
    fmt.Println(s)             // 输出:[10 0 0 20 30 40]
    fmt.Println(len(s), cap(s)) // 输出:6 10(容量通常翻倍)
}

2. 创建映射(Map)

场景

语法

make(map[K]V, hint)

示例

package main

import "fmt"

func main() {
    // 创建一个空的映射
    m := make(map[string]int)
    fmt.Println(m) // 输出:map[]

    // 添加键值对
    m["Alice"] = 25
    m["Bob"] = 30
    fmt.Println(m) // 输出:map[Alice:25 Bob:30]

    // 访问键值对
    fmt.Println(m["Alice"]) // 输出:25

    // 检查键是否存在
    value, exists := m["Charlie"]
    fmt.Println(value, exists) // 输出:0 false

    // 删除键
    delete(m, "Bob")
    fmt.Println(m) // 输出:map[Alice:25]
}

3. 创建通道(Channel)

场景

语法

make(chan T, bufferSize)

示例

package main

import "fmt"

func main() {
    // 创建一个无缓冲通道
    ch := make(chan int)

    // 使用 goroutine 发送数据
    go func() {
        ch <- 42
    }()

    // 接收数据
    value := <-ch
    fmt.Println(value) // 输出:42

    // 创建一个有缓冲通道
    chBuffered := make(chan int, 2)
    chBuffered <- 10
    chBuffered <- 20
    fmt.Println(<-chBuffered) // 输出:10
    fmt.Println(<-chBuffered) // 输出:20
}

4. 与 new 的区别

Go 中除了 make,还有另一个内置函数 new,它们的作用不同:

特性 make new
适用类型 仅适用于切片(Slice)、映射(Map)、通道(Channel) 适用于所有类型
返回值 返回初始化后的引用类型(非指针) 返回指向零值的指针
主要用途 分配内存并初始化内部数据结构 仅分配内存,不初始化

示例:

package main

import "fmt"

func main() {
    // 使用 make 创建切片
    s := make([]int, 3)
    fmt.Println(s) // 输出:[0 0 0]

    // 使用 new 创建数组指针
    p := new([3]int)
    fmt.Println(*p) // 输出:[0 0 0]
}

5. 使用场景总结

切片(Slice)

映射(Map)

通道(Channel)


6. 注意事项

  1. 不能用 make 创建其他类型

    • make 只能用于切片、映射和通道,不能用于数组、结构体等其他类型。
    • 对于其他类型的初始化,通常使用 new 或直接字面量赋值。
  2. 切片的容量提示

    • 使用 make([]T, len, cap) 时,cap 的设置可以减少切片扩容的次数,从而提高性能。
  3. 映射的容量提示

    • make(map[K]V, hint) 中的 hint 只是容量的提示,Go 不会强制遵守该值。
  4. 通道的缓冲区大小

    • 无缓冲通道会导致发送和接收操作阻塞,适用于严格同步的场景。
    • 有缓冲通道允许一定数量的数据缓冲,适用于异步通信场景。

总结

make 是 Go 中用于创建和初始化切片、映射和通道的关键工具。它的使用场景非常明确:

通过合理使用 make,可以高效地管理内存并初始化复杂的数据结构。

上一篇 下一篇

猜你喜欢

热点阅读