当前位置: 首页 > news >正文

Go语言的内置容器

文章目录

  • 一、数组
      • 数组的定义
      • 数组声明
      • 数组特点
      • 数组元素修改
  • 二、切片
      • 切片声明
      • 基于数组创建切片
      • 使用make()函数构造切片
      • 使用append()为切片动态添加元素\
      • 使用copy()复制新的切片
      • 数组与切片相互转换
  • 三、Map映射
      • Map定义
      • 使用make()函数创建map
      • 用切片作为map的值
      • 使用delete()函数删除元素

一、数组

数组的定义

一个由固定长度的特定元素组成的序列

数组声明

标准格式声明数组:

var variable_name [size]type

初始化数组:

var variable_name = [size]type{value,...}

编译器自行推断数组大小:

var variable_name = [...]type {value,...}

一些示例:

//示例1
var a [3] int  //声明一个数组为 a ,类型为int,大小为3的数组
a[0] = 12 //为第一个元素填充数据,为12
a[1] = 13 //为第二个元素填充数据,为13
a[2] = 14 //为第三个元素填充数据,为14//示例2
var a = [3] int {12,13,14} //定义且声明数组内容//示例3
a := [3]int {12,13,14}//定义且声明数组内容//示例4
a := [3]int{12}//可以只填充部分数据//示例5
a := [3]int {1:13,2:14}//填充指定位置//示例6
a := [...]int{12,13,14}//编译器自行判断数组长度

数组特点

  • 数组的每个元素可以通过索引下标来访问
  • 索引下标的范围从0开始到数据长度减1结束
  • 数组无法灵活扩容:在定义数组元素数量后,赋值元素变量个数必须要小于或者等于预设值的元素数量
  • type指任意的基本类型,也可以是数组本身,实现多维数组
  • 在Go语言中数组是值类型而不是引用类型
  • 这意味着当数组变量被赋值时,将会获得原数组的拷贝,新数组中元素的改变不会影响原数组中元素的值

示例:

package main
import "fmt"
func main() {a := [...]int{12, 78, 50}b := a	// 将a数组复制给b数组b[0] = 60fmt.Println(a)fmt.Println(b)
}//运行结果为:
//[12 78 50]
//[60 78 50]

数组元素修改

package main
import "fmt"
func main() {var a [1]string                          //定义一个1个元素的string类型数组,string默认值为空var b = [2]string{“a”, “b”}  //定义一个2个元素的string类型数组c := [3]string{"a", "b", "c"}         //定义并初始化一个3个空间的string类型数组d := [...]string{"a", "b", "c", "d"} //自动推到元素个数e := d                                        //拷贝数组e[0] = "e"                                  //修改数组指定位置的值fmt.Println(a, len(a))                 //打印a数组、a数组长度fmt.Println(b)fmt.Println(c)fmt.Println(d, len(d))fmt.Println(e, len(e))
}//运行结果为:
//[] 1
//[a b]
//[a b c]
//[a b c d] 4
//[e b c d] 4

二、切片

数组和切片的对比
在这里插入图片描述

切片声明

切片声明:

var name[]type = []type{......}

切片特点:

  • []中不需要指定长度,即长度是不固定的
  • 可以追加元素,在追加时可能使切片的容量增大,可以从数据中生成新的切片或者是声明新的切片

示例:

package main
import "fmt"
func main() {var a []int= []int{10,11,12,13}fmt.Println(a,len(a))
}//运行结果为:
//[10 11 12 13] 4

基于数组创建切片

var name [] type = 数组名[开始位置:结束位置]

特点:

  • 结束位置的元素不取
  • 切片数量 = 结束位置下标 - 开始位置下标
  • 当缺省开始位置时,表示从连续的区域开头到结束位置
    在编程和数据处理领域,"缺省"(或“默认”)通常指的是在没有明确指定某个值或选项时,系统或程序将自动采用的一个预设值或行为。这个预设值或行为被称为“缺省值”或“默认值”。
  • 当缺省结束位置时,表示从开始位置到整个连续区域末尾
  • 两者同时缺省时,与数组本身等效
  • 两者同时为0时,等于空切片,一般用于切片复位

示例:


//示例1
package main
import "fmt"
func main() {a := [5]string{"A","B","C","D"}var b []string = a[1:2]fmt.Println(a)fmt.Println(b,len(b))
}//运行结果为:
//[A B C D ]
//[B] 1
//示例2
package main
import "fmt"
func main() {a := [5]int{76, 77, 78, 79, 80}var b []int = a[1:3]	//取a数组的第1到第3个元素var c []int = a[:3]	//取a数组的第0到第3个元素var d []int = a[1:]	//取a数组的第1到最后一个元素var e []int = a[:]	//取a数组的第0到最后一个元素var f []int = a[0:0]	//空切片fmt.Println(a,len(a))fmt.Println(b,len(b))fmt.Println(c,len(c))fmt.Println(d,len(d))fmt.Println(e,len(e))fmt.Println(f,len(f))
}//运行结果为:
//[76 77 78 79 80] 5
//[77 78] 2
//[76 77 78] 3
//[77 78 79 80] 4
//[76 77 78 79 80] 5
//[] 0
  • 切片本身不包含任何数据
  • 切片是底层数组的一个上层表示
  • 对切片进行的任何修改都将反映在底层数据化中
package main
import "fmt"
func main() {a := [5]string{"A","B","C","D","E"}var b []string = a[1:3]fmt.Println("修改前的a数组:",a)fmt.Println("修改前的b切片:",b)b[1]="2"fmt.Println("修改后的a数组:",a)fmt.Println("修改后的b切片:",b)
}//运行结果为:
//修改前的a数组: [A B C D E]
//修改前的b切片: [B C]
//修改后的a数组: [A B 2 D E]
//修改后的b切片: [B 2]
  • 切片的长度是指切片中元素的个数
  • 切片的容量是指从切片的起始元素开始到其底层数组中的最后一个元素的个数
  • 切片的长度可以动态的改变(最大为其容量)
  • 任何超出最大容量的操作都会发生运行时错误
package main
import ("fmt"
)
func main() {a := [...]string{"A", "B", "C", "D", "E"}b := a[1:3]fmt.Printf("数组a长度为:%d \n切片b容量为:%d", len(a), cap(b))
}//运行结果为:
//数组a长度为:5 
//切片b容量为:4

使用make()函数构造切片

var name [] type = make([]type,size,cap)

特点:

  • type指切片元素类型
  • size 指的是为这个类型分配多少个元素
  • cap 为预分配的元素数量
  • cap设定后不会影响 size,只是为了提前分配空间,降低多次分配空间造成的性能问题
package main
import "fmt"
func main() {var a [] int =make([]int,5,10)
//创建一个切片,初始元素个数为5,并预留10个元素的存储空间a[0]=10a[4]=14fmt.Println("切片内容:", a)fmt.Println("切片长度:", len(a))fmt.Println("切片容量:", cap(a))
}//运行结果为:
//切片内容: [10 0 0 0 14]
//切片长度: 5
//切片容量: 10

使用append()为切片动态添加元素\

append(name,value)
append(name,[]type[value,value,value]...)

特点:

  • 可以为切片追加单个或多个元素;或者是追加切片
  • 使用append()函数为切片动态添加元素时,如果空间不足以容纳足够多的元素,切片就会进行“扩容”,此时新切片的长度会发生改变。
  • 扩展容量小于1024个元素时按当前切片的容量(Cap)2倍扩容,扩展容量大于1024个元素时按Cap的1/4扩容。
package main
import“fmt”
func main() {a := []int{10, 20, 30, 40, 50}b := a[1:3]fmt.Println(a)fmt.Println(b)b = append(b, 60)fmt.Printf(“第一次追加后,切片a为:%d 切片a容量为:%d\n", a, cap(a))fmt.Printf(“第一次追加后,切片b为:%d 切片b容量为:%d\n", b, cap(b))b = append(b, 70,80,90,100)fmt.Printf(“第二次追加后,切片a为:%d 切片a容量为:%d\n", a, cap(a))fmt.Printf(“第二次追加后,切片b为:%d 切片b容量为:%d\n", b, cap(b))
}//运行结果为:
//[10 20 30 40 50]
//[20 30]
//第一次追加后,切片a为:[10 20 30 60 50] 切片a容量为:5
//第一次追加后,切片b为:[20 30 60] 切片b容量为:4
//第二次追加后,切片a为:[10 20 30 60 50] 切片a容量为:5
//第二次追加后,切片b为:[20 30 60 70 80 90 100] 切片b容量为:8

在对切片 b 进行第一次 append 时,由于它仍然指向 a 的底层数组,因此 a 和 b 共享数据;但第二次 append 超出容量时,切片 b 就会分配新的底层数组,不再共享 a 的数据。

使用copy()复制新的切片

copy(destSlice,srcSlice)

特点:

  • destSlice 为复制的目标切片
  • srcSlice 为数据来源切片
  • 目标切片必须分配过空间且足够承载复制的元素个数,并且来源和目标的类型必须一致。
  • copy() 函数来源切片和目标切片可以共享同一个底层数组,甚至有重叠也没有问题。
package main
import "fmt"
func main() {a := []int{0,1,2,3,4,5}b := []int{10,11,12}fmt.Println(a)fmt.Println(b)copy(b,a)  // 只会复制a的前3个元素到b中fmt.Println(a)fmt.Println(b)
}//运行结果为:
//[0 1 2 3 4 5]
//[10 11 12]
//[0 1 2 3 4 5]
//[0 1 2]

数组与切片相互转换

  • 需要使用[:]将数组伪装为切片类型后再进行赋值,否则无法通过编译
  • 数组与切片中的元素类型必须相同

切片转成数组:

package main
import "fmt"
func main() {//切片转成数组s := []int{10, 11, 12}var a [3]intfmt.Println(copy(a[:], s))fmt.Println(a)
}//运行结果为:
//3
//[10 11 12]

数组转成切片:

package main
import "fmt"
func main() {//数组转成切片a := [...]int{10, 11, 12}b := make([]int, 3)fmt.Println(copy(b, a[:]))fmt.Println(b)
}//运行结果为:
//3
//[10 11 12]

三、Map映射

Map定义

一种无序的Key/value的集合
能够通过key值快速检索数据值
map这种数据结构在其他编程语言中也称为字典、映射或哈希表。
Golang的map由两种重要的结构构成:hmap和bmap

声明map集合:

var name map[key_type]value_type

语法说明如下:

  1. name为map变量名
  2. key_type为键类型
  3. value_type为键值对应值类型
package main
import "fmt"
func main() {a:=map[int]string{110:"报警电话",120:"急救电话",119:"消防电话"}fmt.Println(a)
}//运行结果为:
//map[110:报警电话 119:消防电话 120:急救电话]

使用make()函数创建map

make(map[KeyType]ValueType, [cap])

特点:

  • map可以在声明的时候填充元素,也可以单独填充元素
  • map中的数据都是成对出现的
  • map类型的变量默认初始值为nil
  • 其中cap表示map的容量,该参数虽然不是必须的,但是我们应该在初始化map的时候就为其指定一个合适的容量。

用切片作为map的值


//示例1package main
import "fmt"
func main() {a := make(map[string]int,10)a["报警电话"] = 110;a["急救电话"] = 120;a["火警电话"] = 119;fmt.Println(a)
}//运行结果为:
//map[急救电话:120 报警电话:110 火警电话:119]

//示例2
package main
import "fmt"
func main() {//map的值为切片:a := make(map[int][]string, 2)// 创建一个容量为 2 的 map,键为 int,值为 []string(切片)a[1] = make([]string, 0, 2)      // 为键 1 初始化一个长度为 0、容量为 2 的切片a[1] = append(a[1], "A", "a") // 向切片中追加元素 "A" 和 "a"fmt.Println(a)
}//运行结果为:
//map[1:[A a]]

//示例3
package main
import "fmt"
func main() {//切片的元素类型为map:b := make([]map[string]int, 2)b[0] = make(map[string]int, 2)b[0]["A"] = 1b[0]["a"] = 2fmt.Println(b)
}//运行结果为:
//[map[A:1 a:2] map[]]

使用delete()函数删除元素

delete(map,key)

特点:

  • 如果要删除的key不存在,那么这个调用将什么都不发生,也不会有什么副作用
  • 但是如果传入的map变量的值是nil,该调用将导致程序抛出异常(panic)
示例
package main
import "fmt"
func main() {a:=map[int]string{110:"报警电话",120:"急救电话",119:"消防电话"}delete(a,110)fmt.Println(a)
}//运行结果为:
//map[119:消防电话 120:急救电话]
http://www.lryc.cn/news/479489.html

相关文章:

  • HCIP考试怎样预约?随时可以考试吗?
  • 香港航空 阿里滑块 acw_sc__v3 分析
  • JS传统函数中常见的 this 绑定问题
  • 跨域问题以及使用vscode的LiveServer插件跨域访问
  • 现代Web开发:WebSocket 实时通信详解
  • 《深度学习》——深度学习基础知识(全连接神经网络)
  • nginx 部署2个相同的vue
  • 利用Java easyExcel库实现高效Excel数据处理
  • Vulnhub靶场 Metasploitable: 1 练习(上)
  • 《Python编程实训快速上手》第二天--列表与元组
  • jangow靶机
  • 使用UDP协议传输视频流!(分片、缓存)
  • Pinia小菠萝(状态管理器)
  • Python知识点:基于Python工具,如何使用Web3.py进行以太坊智能合约开发
  • 【简信CRM-注册安全分析报告】
  • ssm+vue694基于Java的药店药品信息管理系统的设计与实现
  • Sentinel微服务保护
  • 喜讯!实在Agent智能体入选《2024年度最佳企业服务AI产品榜》
  • Aop+自定义注解实现数据字典映射
  • 大语言模型(LLM)入门级选手初学教程 III
  • STM32G0xx使用LL库将Flash页分块方式存储数据实现一次擦除可多次写入
  • SAP B1 认证考试习题 - 解析版(三)
  • 数据库开发规范
  • 使用python向钉钉群聊发送消息
  • YOLOv11改进:SE注意力机制【注意力系列篇】(附详细的修改步骤,以及代码,与其他一些注意力机制相比,不仅准确度更高,而且模型更加轻量化。)
  • STM32 基于HAL库和STM32cubeIDE的应用教程 (二)--GPIO的使用
  • 【毫米波雷达(七)】自动驾驶汽车中的精准定位——RTK定位技术
  • Transformer和BERT的区别
  • linux 加载uPD720201固件
  • C语言中的信号量semaphore详解