GO语言容器大全(附样例代码)

在Go语言中,虽然没有像其他语言那样内置的复杂集合框架,但标准库提供的数据结构足以满足大部分常见需求。下面,我们将深入探讨切片(slice)、映射(map)和通道(channel)这三种基本容器,并通过代码示例来加深理解。

切片(Slice)

切片是Go语言中动态数组的实现,它提供了灵活且强大的功能来管理一组同类型的数据。切片是对数组的抽象,它提供了动态扩容的能力,使得我们可以根据需要动态地增加或减少元素的数量。

package main  
  
import (  
    "fmt"  
)  
  
func main() {  
    // 创建一个空的整数切片  
    var numbers []int  
  
    // 使用append函数向切片中追加元素  
    numbers = append(numbers, 1)  
    numbers = append(numbers, 2, 3)  
    numbers = append(numbers, 4, 5, 6)  
  
    // 打印切片内容  
    fmt.Println(numbers) // 输出: [1 2 3 4 5 6]  
  
    // 切片的切片操作  
    sliceOfSlice := numbers[1:4] // 创建一个从索引1到3(不包括4)的子切片  
    fmt.Println(sliceOfSlice)   // 输出: [2 3 4]  
  
    // 切片的扩容  
    numbers = append(numbers, 7, 8, 9, 10)  
    fmt.Println(numbers) // 输出可能类似于: [1 2 3 4 5 6 7 8 9 10]  
  
    // 切片的拷贝  
    copyOfNumbers := make([]int, len(numbers))  
    copy(copyOfNumbers, numbers)  
    fmt.Println(copyOfNumbers) // 输出与numbers相同  
}

在上面的代码中,我们展示了如何创建切片、向切片中添加元素、如何从切片中创建子切片、如何扩容切片,以及如何拷贝切片。

映射(Map)

映射是Go语言中的关联数组,用于存储键值对。映射的键必须是可比较的类型,而值可以是任意类型。

package main  
  
import (  
    "fmt"  
)  
  
func main() {  
    // 创建一个空的字符串到整数的映射  
    var ages map[string]int  
  
    // 初始化映射  
    ages = make(map[string]int)  
  
    // 向映射中添加键值对  
    ages["Alice"] = 25  
    ages["Bob"] = 30  
    ages["Charlie"] = 35  
  
    // 打印映射内容  
    fmt.Println(ages) // 输出类似于: map[Alice:25 Bob:30 Charlie:35]  
  
    // 从映射中获取值  
    aliceAge, exists := ages["Alice"]  
    if exists {  
        fmt.Printf("Alice's age is %d\n", aliceAge)  
    }  
  
    // 删除映射中的键值对  
    delete(ages, "Bob")  
    fmt.Println(ages) // Bob被删除了  
  
    // 遍历映射  
    for name, age := range ages {  
        fmt.Printf("%s is %d years old\n", name, age)  
    }  
}

在上面的代码中,我们展示了如何创建映射、向映射中添加键值对、从映射中获取值、删除映射中的键值对,以及如何遍历映射。

通道(Channel)

通道是Go语言中用于协程(goroutine)之间通信的一种机制。通道提供了一种安全的方式来传递数据,确保数据在发送和接收之间同步。

package main  
  
import (  
    "fmt"  
    "time"  
)  
  
func main() {  
    // 创建一个可以传递整数的通道  
    ch := make(chan int)  
  
    // 启动一个并发的goroutine来向通道发送数据  
    go func() {  
        time.Sleep(2 * time.Second) // 模拟耗时操作  
        ch <- 42                    // 向通道发送整数42  
    }()  
  
    // 从通道接收数据并打印  
    value := <-ch // 阻塞,直到接收到数据  
    fmt.Println(value) // 输出: 42  
}

在上面的代码中,我们展示了如何创建一个通道,并在一个并发的goroutine中向通道发送数据。主goroutine会阻塞在接收操作上,直到数据被发送到通道中。

列表(List)

Go语言的container/list包提供了一个双向链表实现。双向链表允许你在列表的任何位置高效地插入和删除元素。

package main  
  
import (  
	"container/list"  
	"fmt"  
)  
  
func main() {  
	// 创建一个新的双向链表  
	l := list.New()  
  
	// 在链表尾部添加元素  
	l.PushBack(1)  
	l.PushBack(2)  
	l.PushBack(3)  
  
	// 在链表头部添加元素  
	l.PushFront(0)  
  
	// 遍历链表并打印元素  
	for e := l.Front(); e != nil; e = e.Next() {  
		fmt.Println(e.Value)  
	}  
}

在这个例子中,我们创建了一个双向链表,并在其尾部和头部添加了元素。然后,我们遍历链表并打印出每个元素的值。

堆(Heap)

container/heap包提供了堆的实现,它允许你实现任意类型的堆,包括最小堆和最大堆。堆是一种特殊的树形数据结构,它满足父节点的值总是小于或等于(在最小堆中)或大于或等于(在最大堆中)其子节点的值。

package main  
  
import (  
	"container/heap"  
	"fmt"  
)  
  
// IntHeap 是一个由整数组成的最小堆  
type IntHeap []int  
  
func (h IntHeap) Len() int           { return len(h) }  
func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }  
func (h IntHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }  
  
func (h *IntHeap) Push(x interface{}) {  
	*h = append(*h, x.(int))  
}  
  
func (h *IntHeap) Pop() interface{} {  
	old := *h  
	n := len(old)  
	x := old[n-1]  
	*h = old[0 : n-1]  
	return x  
}  
  
func main() {  
	h := &IntHeap{2, 1, 5}  
	heap.Init(h)  
	heap.Push(h, 3)  
	fmt.Printf("minimum: %d\n", (*h)[0])  
	for h.Len() > 0 {  
		fmt.Printf("%d ", heap.Pop(h))  
	}  
}

在这个例子中,我们定义了一个IntHeap类型,它实现了heap.Interface接口所需的方法,从而使其可以作为一个最小堆来使用。我们初始化了一个堆,并向其中添加了一个元素。然后,我们打印出堆中的最小元素,并依次弹出并打印堆中的所有元素。

第三方容器库

除了标准库提供的数据结构之外,Go语言的开源社区也有许多优秀的第三方库,提供了更多种类的容器实现,如并发安全的队列、栈、环形缓冲区等。这些库通常提供了更高级的功能和更好的性能优化。

例如,一些流行的第三方容器库包括:

  • github.com/deckarep/golang-set:一个Go语言的集合库,提供了集合的基本操作。
  • github.com/goccy/go-graphviz:一个用于创建图形和可视化的库,虽然不是传统意义上的容器,但可以用于构建复杂的数据结构图。
  • github.com/workanator/go-floc:一个流式数据流处理库,提供了高级的数据流操作和并发处理功能。
总结

Go语言虽然没有内置的复杂集合框架,但通过其标准库和丰富的开源社区资源,开发者可以轻松地找到满足其需求的容器实现。无论是切片、映射、通道,还是列表、堆,甚至是更复杂的第三方容器库,Go语言都提供了灵活且高效的工具来管理数据。

希望这些详细的介绍和代码示例能帮助你更好地理解Go语言中的容器,并为你的Go编程之旅提供有力的支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/713848.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

手机照片免费数据恢复软件EasyRecovery2024免费版下载

大家好&#xff01;今天我要给大家推荐一款非常棒的软件——EasyRecovery。相信大家都知道&#xff0c;电脑中的重要文件一旦丢失&#xff0c;对我们的工作和学习都会产生很大的影响。 而EasyRecovery软件就是专门解决这个问题的利器&#xff01;它能够帮助我们快速、有效地恢…

第三篇—基于黑白样本的webshell检测

本篇为webshell检测的第三篇&#xff0c;主要讲的是基于黑白样本的webshell预测&#xff0c;从样本收集、特征提取、模型训练&#xff0c;最后模型评估这四步&#xff0c;实现一个简单的黑白样本预测模型。   若有误之处&#xff0c;望大佬们指出 Ⅰ 基本实现步骤 样本收集&…

Unity中的伽马(Gamma)空间和线性(Linear)空间

伽马空间定义&#xff1a;通常用于描述图像在存储和显示时的颜色空间。在伽马空间中&#xff0c;图像的保存通常经过伽马转换&#xff0c;使图片看起来更亮。 gamma并不是色彩空间&#xff0c;它其实只是如何对色彩进行采样的一种方式 为什么需要Gamma&#xff1a; 在游戏业…

53. QT插件开发--插件(动态库so)的调用与加载

1. 说明 在使用QT进行插件库的开发之后,还需要将这个插件库程序生成的so动态链接库加载到主程序框架中进行使用,才能达到主程序的模块化开发的效果。在前一篇文章插件创建中介绍了如何在QT中开发插件库,并提供外部接口调用。本篇博客的主要作用是模拟在主程序框架中加载动态…

诊断丢帧:发送端连续帧发送过快,导致接收端丢帧

项目场景: 在项目开发过程中,对于报文的接收/发送,一般来说,通信量大,选择Polling(轮询)处理模式;通信量小,选择Interrupt(中断)处理模式。具体选择没有优劣之分。结合项目的实际情况,选择适合项目的方式就好。小编将分享一个Polling模式下出现的丢帧现象。 1576…

Docker镜像技术剖析

目录 1、概述1.1 什么是镜像&#xff1f;1.2 联合文件系统UnionFS1.3 bootfs和rootfs1.4 镜像结构1.5 镜像的主要技术特点1.5.1 镜像分层技术1.5.2 写时复制(copy-on-write)策略1.5.3 内容寻址存储(content-addressable storage)机制1.5.4 联合挂载(union mount)技术 2.机制原理…

C# WPF入门学习主线篇(十五)—— DockPanel布局容器

C# WPF入门学习主线篇&#xff08;十五&#xff09;—— DockPanel布局容器 欢迎来到C# WPF入门学习系列的第十五篇。在前几篇文章中&#xff0c;我们探讨了 Canvas、StackPanel 和 WrapPanel 布局容器及其使用方法。本篇博客将介绍另一种强大且常用的布局容器——DockPanel。…

打造成功的人力RPO项目:赢得市场赚取利润

人力资源外包(RPO)项目是当今企业在招聘和人才管理方面越来越倾向的选择。想要通过人力RPO项目赚钱&#xff0c;以下是一些关键的策略和步骤&#xff0c;帮助您进入这个市场并取得成功。 1. 建立专业的人力RPO服务 首先&#xff0c;要想在人力RPO项目中赚钱&#xff0c;必须建立…

HCIA11 网络安全之本地 AAA 配置实验

AAA 提供 Authentication&#xff08;认证&#xff09;、Authorization&#xff08;授权&#xff09;和 Accounting&#xff08;计费&#xff09;三种安全功能。 • 认证&#xff1a;验证用户是否可以获得网络访问权。 • 授权&#xff1a;授权用户可以使用哪些服务。 •…

AOP切面加自定义注解,实现日志记录

AOP切面加自定义注解&#xff0c;实现日志记录 一、AOP二、准备工作三、添加AOP&#xff0c;把日志保存到数据库 一、AOP 在软件业&#xff0c;AOP为Aspect Oriented Programming的缩写&#xff0c;意为&#xff1a;面向切面编程&#xff0c;通过预编译方式和运行期动态代理实…

debug调试高级功能 断点、布局 及Android Studio常用快捷按键使用详情

文章目录 debug断点篇&#xff1a;打临时断点&#xff08;只用一次&#xff09;&#xff1a;alt断点条件断点&#xff1a;在断点上&#xff0c;点击右键&#xff0c;在Condition那里&#xff0c;设置我们需要的值&#xff0c;循环就会自动停到我们设置的那个值那里依赖断点&…

Markdown如何分页操作

Markdown导出分页操作 在平时的文档导出过程中Markdown过程中会出现因为不能分页导致的排版问题。 排版问题在将Markdown文档导出为PDF或其他格式时尤为明显。当文档内容超过一页时&#xff0c;无法自动调整页面布局&#xff0c;导致内容不连续&#xff0c;甚至导致图片或表格…

pve8群晖rr方式安装(编译失败检查网络或磁盘空间error 23:200问题解决)

PVE 篇二&#xff1a;2024年PVE8最新安装使用指南|安装黑群晖&#xff5c;img格式镜像安装_NAS存储_什么值得买 (smzdm.com) 黑群晖 篇五&#xff1a;2023黑群晖最新安装方式|RR新手也可轻松上手_NAS存储_什么值得买 (smzdm.com) 编译引导提示&#xff1a;检查网络或磁盘空间er…

qt dll编写和调用

dll编写 新建项目 头文件 #ifndef LIB1_H #define LIB1_H#include "lib1_global.h"class LIB1_EXPORT Lib1 { public:Lib1(); };//要导出的函数&#xff0c;使用extern "C"&#xff0c;否则名称改变将找不到函数extern "C" LIB1_EXPORT int ad…

程序员的核心职业素养:专业、沟通与持续学习

✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的点赞、关注、收藏、评论&#xff0c;是对我最大…

单片机第五季-第八课:STM32CubeMx和FreeRTOS

1&#xff0c;FreeRTOS背景介绍 RTOS简介&#xff1a; 实时操作系统&#xff0c;本用于追求实时性的嵌入式系统&#xff0c;典型&#xff1a;ucos/uclinux/vxworks&#xff1b; 特点&#xff1a;中断响应快、一般可嵌套中断、使用实地址、多任务&#xff1b; &#xff08;实…

中国历年人均发电量统计报告

数据来源于国家统计局&#xff0c;为1978年到2020年我国每年的人均发电量数据。 2020年&#xff0c;我国人均发电量为5512.76千瓦时&#xff0c;比上年增长3.4%。 数据统计单位为&#xff1a;千瓦时 我国人均发电量有多少&#xff1f; 2020年&#xff0c;我国人均发电量为5512…

一键自动粘贴,高效处理邮箱地址,让你的工作效率翻倍提升!

在信息爆炸的时代&#xff0c;邮箱地址已成为我们日常工作和生活中的必备元素。无论是商务沟通、报名注册还是信息传递&#xff0c;邮箱地址都扮演着至关重要的角色。然而&#xff0c;手动复制粘贴邮箱地址的繁琐操作往往让人头疼不已&#xff0c;不仅效率低下&#xff0c;还容…

代码随想录第29天|贪心算法part3

134.加油站 首先如果总油量减去总消耗大于等于零那么一定可以跑完一圈 每个加油站的剩余量rest[i]为gas[i] - cost[i] 从0开始累加rest[i]&#xff0c;和记为curSum&#xff0c;一旦curSum小于零&#xff0c;说明[0, i]区间都不能作为起始位置 因为我们一直维护的是一个剩余量大…

Linux磁盘格式化与重新分区

1.df -BG查看磁盘挂载情况 2.fdisk -l查看磁盘详细信息 3.sudo mkfs.ext4 /path 格式化磁盘 4.挂载格式化后磁盘 挂载成功