设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间01 现在时间01 缓存数据 当你走完一段之后回头看,你会发现,那些真正能被记得的事真的是没有多少,真正无法忘记的人屈指可数,真正有趣的日子不过是那么一些,而真正需要害怕的也是寥寥无几。

当你走完一段之后回头看,你会发现,那些真正能被记得的事真的是没有多少,真正无法忘记的人屈指可数,真正有趣的日子不过是那么一些,而真正需要害怕的也是寥寥无几。

查看: 763|回复: 0

Go语言使用make进行内存分配的代码示例

[复制链接]

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
52
主题
42
精华
0
金钱
147
积分
96
注册时间
2023-10-4
最后登录
2025-9-8

发表于 2025-9-8 08:37:54 | 显示全部楼层 |阅读模式
make 函数的基本概念


语法与适用类型
  1. make
复制代码
函数的语法格式为
  1. make(T, args)
复制代码
,其中
  1. T
复制代码
代表要创建的类型,必须是切片、映射或通道这三种引用类型之一,
  1. args
复制代码
是根据不同类型而定的参数。以下是三种类型使用
  1. make
复制代码
函数的基本形式:

  • 切片
    1. make([]T, length, capacity)
    复制代码
    ,其中
    1. T
    复制代码
    是切片元素的类型,
    1. length
    复制代码
    是切片的初始长度,
    1. capacity
    复制代码
    是切片的初始容量(可省略,默认与长度相同)。
  • 映射
    1. make(map[K]V, initialCapacity)
    复制代码
    1. K
    复制代码
    是键的类型,
    1. V
    复制代码
    是值的类型,
    1. initialCapacity
    复制代码
    是映射的初始容量(可省略)。
  • 通道
    1. make(chan T, bufferSize)
    复制代码
    1. T
    复制代码
    是通道中元素的类型,
    1. bufferSize
    复制代码
    是通道的缓冲区大小(可省略,省略时为无缓冲通道)。

代码示例
  1. package main

  2. import "fmt"

  3. func main() {
  4.     // 使用 make 创建切片
  5.     slice := make([]int, 3, 5)
  6.     fmt.Printf("切片长度: %d, 容量: %d, 内容: %v\n", len(slice), cap(slice), slice)

  7.     // 使用 make 创建映射
  8.     m := make(map[string]int)
  9.     m["apple"] = 1
  10.     m["banana"] = 2
  11.     fmt.Println("映射内容:", m)

  12.     // 使用 make 创建通道
  13.     ch := make(chan int, 2)
  14.     ch <- 10
  15.     ch <- 20
  16.     fmt.Println("从通道接收:", <-ch)
  17. }
复制代码
在上述代码中,分别使用
  1. make
复制代码
函数创建了切片、映射和通道,并进行了简单的操作。

切片的 make 分配


长度与容量的区别

在使用
  1. make
复制代码
创建切片时,长度和容量是两个重要的概念。长度表示切片中当前元素的数量,而容量表示切片底层数组的大小。可以通过
  1. len()
复制代码
函数获取切片的长度,通过
  1. cap()
复制代码
函数获取切片的容量。
  1. package main

  2. import "fmt"

  3. func main() {
  4.     // 创建一个长度为 2,容量为 5 的切片
  5.     slice := make([]int, 2, 5)
  6.     fmt.Printf("初始长度: %d, 初始容量: %d\n", len(slice), cap(slice))

  7.     // 向切片追加元素
  8.     slice = append(slice, 1, 2, 3)
  9.     fmt.Printf("追加元素后长度: %d, 容量: %d, 内容: %v\n", len(slice), cap(slice), slice)
  10. }
复制代码
在这个示例中,初始创建的切片长度为 2,容量为 5。当使用
  1. append
复制代码
函数追加元素时,如果长度超过了容量,Go 语言会自动重新分配更大的底层数组。

项目场景:数据处理

在数据处理项目中,我们可能需要动态地处理一批数据。使用
  1. make
复制代码
创建切片可以预先分配一定的容量,减少内存重新分配的次数,提高性能。
  1. package main

  2. import (
  3.     "fmt"
  4. )

  5. func processData() []int {
  6.     // 预先分配容量为 100 的切片
  7.     data := make([]int, 0, 100)
  8.     for i := 0; i < 100; i++ {
  9.         data = append(data, i)
  10.     }
  11.     return data
  12. }

  13. func main() {
  14.     result := processData()
  15.     fmt.Println("处理后的数据:", result)
  16. }
复制代码
映射的 make 分配


初始容量的作用

在使用
  1. make
复制代码
创建映射时,指定初始容量可以提高映射的性能。如果预先知道映射可能存储的元素数量,指定合适的初始容量可以减少哈希表扩容的次数。
  1. package main

  2. import "fmt"

  3. func main() {
  4.     // 创建一个初始容量为 10 的映射
  5.     m := make(map[string]int, 10)
  6.     for i := 0; i < 10; i++ {
  7.         key := fmt.Sprintf("key%d", i)
  8.         m[key] = i
  9.     }
  10.     fmt.Println("映射内容:", m)
  11. }
复制代码
项目场景:缓存系统

在缓存系统中,映射可以用于存储缓存数据。使用
  1. make
复制代码
创建映射并指定合适的初始容量,可以提高缓存系统的性能。
  1. package main

  2. import (
  3.     "fmt"
  4. )

  5. type Cache struct {
  6.     data map[string]interface{}
  7. }

  8. func NewCache(capacity int) *Cache {
  9.     return &Cache{
  10.         data: make(map[string]interface{}, capacity),
  11.     }
  12. }

  13. func (c *Cache) Set(key string, value interface{}) {
  14.     c.data[key] = value
  15. }

  16. func (c *Cache) Get(key string) (interface{}, bool) {
  17.     val, exists := c.data[key]
  18.     return val, exists
  19. }

  20. func main() {
  21.     cache := NewCache(20)
  22.     cache.Set("item1", 100)
  23.     val, exists := cache.Get("item1")
  24.     if exists {
  25.         fmt.Println("缓存中获取的值:", val)
  26.     }
  27. }
复制代码
通道的 make 分配


有缓冲通道与无缓冲通道

使用
  1. make
复制代码
创建通道时,可以指定缓冲区大小。如果不指定缓冲区大小,创建的是无缓冲通道,发送和接收操作会阻塞;如果指定了缓冲区大小,创建的是有缓冲通道,只有当缓冲区满时发送操作才会阻塞,只有当缓冲区为空时接收操作才会阻塞。
  1. package main

  2. import "fmt"

  3. func main() {
  4.     // 创建无缓冲通道
  5.     ch1 := make(chan int)
  6.     go func() {
  7.         ch1 <- 10
  8.         fmt.Println("数据已发送到无缓冲通道")
  9.     }()
  10.     fmt.Println("从无缓冲通道接收:", <-ch1)

  11.     // 创建有缓冲通道
  12.     ch2 := make(chan int, 2)
  13.     ch2 <- 20
  14.     ch2 <- 30
  15.     fmt.Println("从有缓冲通道接收:", <-ch2)
  16. }
复制代码
项目场景:并发任务处理

在并发任务处理中,通道可以用于协程之间的通信。使用
  1. make
复制代码
创建合适的通道可以协调不同协程的工作。
  1. package main

  2. import (
  3.     "fmt"
  4. )

  5. func worker(id int, jobs <-chan int, results chan<- int) {
  6.     for j := range jobs {
  7.         fmt.Printf("Worker %d 开始处理任务 %d\n", id, j)
  8.         results <- j * 2
  9.     }
  10. }

  11. func main() {
  12.     const numJobs = 5
  13.     jobs := make(chan int, numJobs)
  14.     results := make(chan int, numJobs)

  15.     // 启动 3 个工作协程
  16.     for w := 1; w <= 3; w++ {
  17.         go worker(w, jobs, results)
  18.     }

  19.     // 发送任务
  20.     for j := 1; j <= numJobs; j++ {
  21.         jobs <- j
  22.     }
  23.     close(jobs)

  24.     // 收集结果
  25.     for a := 1; a <= numJobs; a++ {
  26.         <-results
  27.     }
  28.     close(results)
  29. }
复制代码
总结

make 函数在 Go 语言中是为切片、映射和通道进行内存分配和初始化的重要工具。通过合理使用 make 函数,可以根据不同的需求为这些引用类型分配合适的内存,提高程序的性能和效率。在实际项目中,无论是数据处理、缓存系统还是并发任务处理,make 函数都发挥着关键作用。开发者需要深入理解 make 函数的使用方法和不同类型的特点,根据具体的场景灵活运用。
以上就是Go语言使用make进行内存分配的代码示例的详细内容,更多关于Go make内存分配的资料请关注晓枫资讯其它相关文章!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表