GO入门——4. 数组、切片与map
1. 数组
- 定义数组的格式:var [n],n>=0
- 数组长度也是类型的一部分,因此具有不同长度的数组为不同类型
- 注意区分指向数组的指针和指针数组
//数组的指针
a := [2]int{1, 2}
p := &a
fmt.Println(p) //&[1 2]
//指针数组
x, y := 1, 2
b := [2]*int{&x, &y} //[0xc042034208 0xc042034220]
fmt.Println(b)
- 数组在Go中为值类型
- 数组之间可以使用==或!=进行比较,但不可以使用<或>
- 可以使用new来创建数组,此方法返回一个指向数组的指针
- Go支持多维数组
a := [2][3]int{
{1, 2, 3},
{4, 5, 6}} //最后的}必须在这一行
fmt.Println(a) //[[1 2 3] [4 5 6]]
//长度不同的数组类型不同
var a [2]int
var b [1]int
// a = b 编译错误:cannot use b (type [1]int) as type [2]int in assignment
//直接赋值
c := [2]int{1} //第一个为1,第二个默认为0
d := [20]int{10: 1, 19: 2} //指定固定位置的值
//系统推断类型(长度)
e := [...]int{1, 2, 3}
f := [...]int{1, 2, 3, 19: -1}
//通过new创建指向数组的指针,都可以通过[]来获取和设置数组元素
p1 := new([2]int)
p1[1] = 1
fmt.Println(p1) //&[0 1]
p2 := [2]int{}
p2[1] = 1 //[0 1]
fmt.Println(p2)
2. 切片
其本身并不是数组,它指向底层的数组
作为变长数组的替代方案,可以关联底层数组的局部或全部
为引用类型可以直接创建或从底层数组获取生成
使用len()获取元素个数,cap()获取容量
一般使用make()创建
如果多个slice指向相同底层数组,其中一个的值改变会影响全部
make([]T, len, cap)
其中cap可以省略,则和len的值相同
len表示存数的元素个数,cap表示容量
2.1 reslice
- Reslice时索引以被slice的切片为准
- 索引不可以超过被slice的切片的容量cap()值
- 索引越界不会导致底层数组的重新分配而是引发错误
2.2 append
- 可以在slice尾部追加元素
- 可以将一个slice追加在另一个slice尾部
- 如果最终长度未超过追加到slice的容量则返回原始slice
- 如果超过追加到的slice的容量则将重新分配数组并拷贝原始数据
//数组
a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
//slice
var s []int
//取从[5,len(a))的值放入slice
s = a[5:]
fmt.Println(s) //[6 7 8 9 0]
s[1] = 10 //slice是共享数组的,因此修改slice数组也会修改
fmt.Println(s) //[6 10 8 9 0]
fmt.Println(a) //[1 2 3 4 5 6 10 8 9 0]
//make的三个参数表示类型、len和cap
//当长度超过cap时,该slice的cap将乘以2将内存换一个位置,并将原始数据复制过去
ss := make([]int, 2, 3)
for i := 0; i < 10; i++ {
s1 := append(ss, i) //append的返回值需要注意,当赋值给新的slice时,ss将永远不会改变
fmt.Println(len(ss), cap(ss), ss)
fmt.Println(len(s1), cap(s1), s1)
}
//当slice重新分配内存后,对其值的修改不会影响到之前共享的数组
s2 := a[:2]
fmt.Println(s2)
s2 = append(s2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3)
s2[0] = 100
fmt.Println(a) //[1 2 3 4 5 6 10 8 9 0]
//copy,当长的复制到短的时只复制短的个数,当短的复制到长的时将短的完全复制到长的中
s3 := []int{1, 2, 3, 4, 5, 6}
s4 := []int{7, 8, 9}
copy(s3, s4) //将s4复制到s3
fmt.Println(s3) //[7 8 9 4 5 6]
s3 = []int{1, 2, 3, 4, 5, 6}
copy(s4, s3)
fmt.Println(s4) //[1 2 3]
3 map
类似其它语言中的哈希表或者字典,以key-value形式存储数据
Key必须是支持==或!=比较运算的类型,不可以是函数、map或slice
Map查找比线性搜索快很多,但比使用索引访问数据的类型慢100倍
Map使用make()创建,支持 := 这种简写方式
make([keyType]valueType, cap),cap表示容量,可省略
超出容量时会自动扩容,但尽量提供一个合理的初始值
使用len()获取元素个数
键值对不存在时自动添加,使用delete()删除某键值对
使用 for range 对map和slice进行迭代操作
//声明与赋值,[]中为key类型,其后为value
var m map[string]int
m = map[string]int{}
//通过make创建与声明
var m1 = make(map[int]string)
m2 := make(map[int]string)
//对k-v取值与设值
m1[1] = "ok"
fmt.Println(m1[1]) //ok
delete(m1, 1) //删除key
fmt.Println(m1[1]) //空
//多返回
a, ok := m1[2]
if !ok {
fmt.Println("没有key=2的value") //输出
}
fmt.Println(a, ok) //当不存在key时会返回空,ok=false
//复杂map
var mf map[int]map[string]int
mf = make(map[int]map[string]int) //初始化最外层map
mf[1] = make(map[string]int) //初始化map[1]中的map,仅仅初始化key=1的map
mf[1]["ok"] = 3
fmt.Println(mf[1]["ok"])
4 range
//对于slice,i,v分别为index和slice下标对应的值,可以采用_将值忽略
s := []int{1, 2, 3}
for i, v := range s {
fmt.Println(i, v)
v = 10 //i,v为值的拷贝,修改不影响slice
s[i] = 0 //直接修改了slice
}
fmt.Println(s) //输出[0 0 0]
//对于map,k,v即为map中的key,value
//每次range的顺序可能不一样
m := map[int]string{
1: "ok"}
for k, v := range m {
fmt.Println(v)
m[k] = "okok" //修改map中值也只能通过对m进行直接操作
}
fmt.Println(m) //map[1:okok]
GO入门——4. 数组、切片与map的更多相关文章
- 四、golang内置函数、递归、闭包、数组切片和map
一.总体内容 1.内置函数.递归函数.闭包 2.数组和切片 3.map数据结构 4.package介绍 一.内置函数 注意:值类型用new来分配内存,引用类型用make来分配内存 1.close:主要 ...
- go:内置函数 | 闭包 | 数组 | 切片 | 排序 | map | 锁
内置函数 1.close: 主要是用来关闭channel 2.len:用来求长度,比如string.array.slice.map.channel 3.new与make都是用来分配内存 new用来分配 ...
- Go语言类型(布尔、整型、数组、切片、map等)
1.基本类型 布尔类型:bool 注意:布尔类型不能接受其他类型的赋值,不支持自动或强制的类型转换. 整型:int8.byte(uint8).int16.int.uint.uintptr int.ui ...
- Go语言学习之4 递归&闭包&数组切片&map&锁
主要内容: 1. 内置函数.递归函数.闭包2. 数组与切片3. map数据结构4. package介绍 5. 排序相关 1. 内置函数.递归函数.闭包 1)内置函数 (1). close:主要用来关闭 ...
- go语言之行--数组、切片、map
一.内置函数 append :追加元素到slice里,返回修改后的slice close :关闭channel delete :从map中删除key对应的value panic : 用于异常处理,停 ...
- 窥探Swift之数组安全索引与数组切片
今天是元宵节,祝大家元宵节快乐!在Swift中的数组和字典中下标是非常常见的,数组可以通过索引下标进行元素的查询,字典可以通过键下标来获取相应的值.在使用数组时,一个常见的致命错误就是数组越界.如果在 ...
- golang中不定参数与数组切片的区别
package main import "fmt" func main() { myfunc1(, , , ) //传递不定数量的参数 myfunc2([], , , }) //传 ...
- go语言 类型:数组切片
初看起来,数组切片就像一个指向数组的指针,实际上它拥有自己的数据结构,而不仅仅是个指针.数组切片的数据结构可以抽象为以下3个变量: 1.一个指向原生数组的指针: 2.数组切片中的元素个数: 3.数组切 ...
- Swift语法基础入门二(数组, 字典, 字符串)
Swift语法基础入门二(数组, 字典, 字符串) 数组(有序数据的集) *格式 : [] / Int / Array() let 不可变数组 var 可变数组 注意: 不需要改变集合的时候创建不可变 ...
- go语言中的数组切片:特立独行的可变数组
go语言中的数组切片:特立独行的可变数组 初看go语言中的slice,觉得是可变数组的一种很不错的实现,直接在语言语法的层面支持,操作方面比起java中的ArrayList方便了许多.但是在使用了一段 ...
随机推荐
- Kafka错误“Network is unreachable”和“larger than available brokers”
确定Kafka安装和启动正确,ZooKeeper可以查到所有的Brokers,但执行: kafka-topics.sh --create --zookeeper localhost:2181 --re ...
- noip第13课作业
1. 排身高 [问题描述] 鹏鹏的班上一共有 n 个学生.刚好每个同学的身高互不相同.鹏鹏想知道,所有同学中身高第二高的是谁. 输入格式:输入共两行,第一行有一个整数 n(2≤n≤100),表示 ...
- W-TinyLFU——设计一个现代的缓存
缓存设计是个基础架构领域里的重要话题,本号之前也有谈论过相关话题,点击原文可以看之前的介绍. 近日,HighScalability网站刊登了一篇文章,由前Google工程师发明的W-TinyLFU—— ...
- 微信小程序-flex布局中align-items和align-self区别
首先看看菜鸟教程中关于align-items和align-self的定义 align-items:align-items 属性定义flex子项在flex容器的当前行的侧轴(纵轴)方向上的对齐方式.(对 ...
- verilog选择数据类型时常犯的错误
• 信号可以分为端口信号和内部信号.出现在端口列表中的信号是端口信号,其它的信号为内部信号. • 对于端口信号,输入端口只能是net类型.输出端口可以是net类型,也可以是register ...
- linux 查看、关闭 ssh pts/n登录的用户
1.查看登录用户: [root@TiaoBan- bin]# w :: up days, :, users, load average: 1.90, 1.75, 1.84 USER TTY FROM ...
- 查找对端mac地址
1.ping对端mac: 2.arp命令查找:
- To datafix AR DATE
http://www.cnblogs.com/benio/archive/2012/07/07/2580203.html AR transactions should be created on 6- ...
- Android-Kotlin-抽象类与多态的表现
选择包名,然后右键: 选择Class类型,会有class: 选择File类型,不会自动有class: 目录结构: 定义描述抽象类 Person人类: package cn.kotlin.kotlin ...
- “全栈2019”Java多线程第三十六章:如何设置线程的等待截止时间
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 下一章 "全栈2019"J ...