Go语言学习笔记——容器

数组

  长度固定的连续内存区域

声明数组

var <标识符> [size]T

  其中,size必须是一个在编译期能确定的值,不能在运行期间才能计算确定,如果为空则是一个切片

var a [2]int
var b [4]float64
var c [5][5]string

初始化数组

var a = [5]int{1,2,3}

  如果不确定数组长度,可以写成

var a = [...]int{1,2,3,4,5,6}

  由编译器确定长度,不能像C语言写成缺省的形式,缺省会创建一个切片而非数组

遍历数组

  利用for range循环遍历数组


切片

  大小可变的数组,是一个引用

a := make([]int, 1)
fmt.Printf("%p\t%p\n", &a, a)
a = append(a, 1, 2, 3, 4)
fmt.Printf("%p\t%p\n", &a, a)
//0xc00000c060    0xc000014090
//0xc00000c060    0xc00001c120

  a存的是一个数组的地址,当数组容量不足时,开辟一块新的内存,并将新地址存到a,所以切片是一个引用

对已有数组切片

var a = [10]int{1, 2, 3, 4, 5, 6}
b := a[2:5]

  范围左闭右开,不能是负数也不能超出数组范围

  切片是一个引用,所以修改原数组的内容,切片中的内容会对应改变

声明切片

  缺省数组大小的方式声明

var a []int

  利用make()声明

a := make([]int, 5)
b := make([]int, 5, 10)

  其中第一个参数指类型,第二个参数是切片大小,第三个参数是切片容量,缺省默认等于切片大小

  使用len()计算两个切片的长度都为5

复制切片

  使用copy(dst []Type, src []Type)函数完成深拷贝,copy()返回拷贝的元素数量

a := make([]int, 5)
b := make([]int, 5, 10)
copy(b, a)

添加和删除元素

  使用append()对切片中的元素进行添加和删除

添加元素

  可以一次只添加一个元素,也可以添加一个切片,如果切片容量不够,会扩容为原来2倍大小,扩容后切片指向的地址也会发生改变

a := make([]int, 5)
b := make([]int, 5, 10)
a = append(a, 2)
b = append(b,a...)

  因为扩容后会复制到新的地方,并改变切片存储的地址值,所以当两个切片指向同一内容时,其中一个切片扩容后,两个切片的内容就不再相关

s1 := make([]int, 5)
s2 := s1
fmt.Printf("%p\t%p\n", s1, s2)	//相同,s1,s2中存的同一地址
s1 = append(s1, 1, 2, 3, 4, 5)
fmt.Printf("%p\t%p\n", s1, s2)	//不同,s1扩容后,地址改变
s1[2] = 100
fmt.Println(s1, s2)							//再修改s1的内容,对s2没有影响
删除元素
a := make([]int, 5)
for i,_ := range a{
   a[i] = i+1
}
a = append(a[:2],a[2+1:]...)
fmt.Println(a)	//[1 2 4 5]
//删除了a[2]

映射

  Go提供的映射容器为map,使用散列表实现

使用映射

m := make(map[string]int)
m["hello"] = 2
m["world"] = 5
//单个左值返回映射值
a := m["hello"]
//两个左值,一个返回映射值,一个返回是否有该key
b, c := m["abc"]

  另一种创建映射的方式

m := map[string]int{
   "hello": 5,
   "world": 10,
}

遍历映射

  使用for range迭代遍历,左值为key,value,如果只写一个,则是key

删除映射表中的键值对

delete(map,key)

m := map[string]int{
   "hello": 5,
   "world": 10,
}
delete(m,"hello")

  如果映射中没有该键,不做任何操作

清空映射

  重新为标识符创建一个新映射,原来的映射会沦为垃圾内存,交给垃圾回收处理

线程安全的映射

sync.Map

使用sync.Map

  声明时无需指定键值类型

var m sync.Map
读写删除操作

  可以插入键值类型不同的键值对

var m sync.Map
//用Store方法写
m.Store("hello",123)
m.Store(123,"world")
m.Store(3.14,true)
//用Load方法读,第二个返回值代表是否存在
a, _ := m.Load("hello")
b, _ := m.Load(123)
c, _ := m.Load(3.14)
//用Delete方法删除,参数是key
m.Delete(123)
m.Delete("hello")
m.Delete(3.14)
遍历sync.Map

  使用方法Range(func) 传入回调函数处理,返回值是true继续迭代,false停止迭代

m.Range(func(key, value interface{}) bool {
   fmt.Println(key, value)
   return true
})

列表

  列表是链表容器

初始化列表

l1 := list.New()
var l2 list.List

在列表中插入元素,删除元素

//从后插入
l1.PushBack("123")
//从头插入
e := l1.PushFront("321")
//从指定位置后插入
l1.InsertAfter(123,e)
//从指定位置前插入
l1.InsertBefore(3.14,e)
//删除元素
l1.Remove(e)

  还可以从首尾插入其他列表

遍历列表

  使用for循环遍历,类似C++中容器的迭代器循环

for i := l1.Front(); i != nil; i = i.Next(){
   fmt.Println(i.Value)
}

参考资料

《Go语言从入门到实践》第三章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值