一、容器:存储和组织数据的方式
变量在一定程度上能满足函数及代码要求。如果编写一些复杂算法、结构和逻辑,就需要更复杂的类型来实现。这类复杂类型一般情况下具有各种形式的存储和处理数据的功能,将它们称为“容器(container)”。在很多语言里,容器是以标准库的方式提供,你可以随时查看这些标准库的代码,了解如何创建,删除,维护内存。
1、数组:一段固定长度$的连续内存区域。可修改成员,但是数组大小不可变。
声明数组
var 数组变量名 元素数量T
a、元素数量不能含有到运行时才能确认大小的数值
b、T可以是任意类型
c、多维数组:多个一维数组组成
2、初始化数组
使用初始胡列表进行元素设置
var lesson = [3]string{“math”, “english”, “code”}
也可由编译器确认数组大小
var game = […]{“DOTA2”,”CSGO”,”war3”}
“…” 标识让编译器确定数组大小
3、切片(slice)
切片的内部结构包含地址、大小和容量。切片一般用于快速的操作一块数据集合。
从哪儿开始切数据,切多大的数据。
格式 slice [开始位置:结束位置]
例子:
var a = [3]int{1, 2, 3}
fmt.Println(a, a[1:2])
切片增加了大小的限制,约束了切片对应内存区域,切片使用中无法对切片内部的地址和大小进行手动调整,因此更安全。
4、声明切片
每一种类型都可以拥有其切片类型,表示多个类型元素的连续集合。因此切片类型也可以被声明。
var name []T
var stringlist []string //声明字符串切片
var numlist []int //声明整型切片
var Emptylist []int{} //声明空切片
fmt.Println(len(strList), len(numList), len(EmptyList)) //输出切片大小
fmt.Println(strList, numList, EmptyList) //输出三个切片
fmt.Println(stringlist == nil) //判断切片为空的结果
5、使用make()函数构造切片
make( []T, size, cap )
T:切片的类型
size:切片的元素数量
cap:预分配数量,不影响size,可以降低多次分配空间造成的性能问题
案例:
a := make([]int, 2)
b := make(len(a), 2, 10)
fmt.Println(a, b)
fmt.Println(len(a), len(b))
使用make()函数生成的切片一定发生了内存分配操作,但是给定开始和结束位置的切片,只是将新的切片结构指向已经分配的内存区域,设定开始和结束的位置,不会发生内存分配操作。
6、为切片动态添加元素
append()函数可以对切片进行扩容,扩展规律为2的倍数
var game []string
game = append(game, “DOTA2”, “WAR3”)
oldgame := []string{“大话西游”, “仙剑奇侠传”}
game = append(game, oldgame…)
“…”表示将整个 oldgame添加进去
7、复制切片元素到另一个切片
案例:
package main
import “fmt”
func main() {
const pipelie = 10000
srcData := make([]int, pipelie)
for i := 0; i < pipelie; i++ {
srcData[i] = i
}
refData := srcData
copyData := make([]int, pipelie)
copy(copyData, srcData)
srcData[0] = 999
fmt.Println(refData[0])
fmt.Println(copyData[0], copyData[pipelie-1])
copy(copyData, srcData[4:6])
for i := 0; i < 5; i++ {
fmt.Printf("%d ",copyData[i])
}
}
8、从切片中删除元素,只能通过切片本身的特性来删除,go未提供语法和接口
seq := []string{“a”, “b”, “c”, “d”, “e”}
index := 2
fmt.Println(seq[:index], seq[index+1:])
seq = append(seq[:index], seq[index+1:]…)
fmt.Println(seq)
以被删除元素为分界点,将前后两部分内存重新连接起来
9、映射(map)
map [keytype]valuetype
案例:
game := make(map[string]int)
game[“DOTA2”] = 1111
fmt.Println(game[“DOTA2”])
dota := game[“war3”]
fmt.Println(dota)
10、删除map中的键值对
delete(map, key)
案例:
delete(game, “DOTA2”)
for k, v := range game {
fmt.Println(k, v)
}
但无法清空map 只能重新make一个map
11、并发 go1.9引入了sync.Map
案例:
package main
import (
“fmt”
“sync”
)
func main() {
var game sync.Map
// 将kv保存到sync.Map
game.Store(“DOTA2”, 1)
game.Store(“csgo”, 2)
game.Store(“war3”, 3)
fmt.Println(game.Load(“war3”))
game.Delete(“war3”)
game.Range(func(k, v interface{}) bool {
fmt.Println(“排名”, k, v)
return true
})
}
sync.Map 保证了并发的安全,但是损失了一些性能
- 本文作者: Devops旭
- 本文链接: http://yoursite.com/2020/03/19/go学习笔记day3/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!