【Go 学习笔记】3 -- Go 数组 字典

【Go 学习笔记】3 – Go 数组 字典

分组声明

同时声明多个变量,常量,或者导入多个包时,可以采用分组的方式进行声明

import(
    "fmt"
    "os"
)

# 除非被显式设置为其他值或是iota,每个const分组的第一个常量被默认设置为他的0值
# 第二及后续的常量被默认设置为它前面那个常量的值。
# 如果前面那个常量的值是 iota ,则它也被设置为 iota
const(
    i = 100
    pi = 3.1415
    value = name
)

var(
    i int
    pi float32
    value string
)

IOTA 枚举

iota 这个关键字用来声明 enum 的时候采用。它默认从 0 开始,每次调用加 1

const(
    x = iota   // x == 0
    y = iota   // y == 1
    z = iota   // z == 2
    w //常量声明省略时,默认和之前一个值的字面相同。这里w = iota =3 
)

# 遇到一个const关键字,iota就会重置。这里 v == 0
const v = iota 

# iota 在同一行的时候,值相同
const(
    // 这里 e == f == g == 0
    e, f, g = iota, iota, iota 
)

array 数组

定义方式var arr [n]tpye
[n]type n 代表数组长度,tpye 表示存储元素的类型。
对数组的操作 都是通过[]来进行处理的。

var arr [10]int
arr[0] = 42  // 数组下标从 0 开始
arr[1] = 13
fmt.Printf("The first element is %d\n",arr[0])
// 获取一个未赋值的最后一个元素,默认返回 0
fmt.Printf("The last element is %d\n",arr[9])

由于长度也是数组的一部分,所以,[3]int[4]int 是不同的类型。
数组是不能改变长度的。
数组之间的赋值 是值的赋值,即当把一个数组作为参数传入函数的时候,传入的其实是这个数组的副本,而不是指针。如果要使用指针,就需要用到 slice 类型。
数组也可以使用 := 来声明

a := [3]int{1, 2, 3}
//声明长度为10的数组,前三个元素值是1,2,3 其他默认为 0
b := [10]int{1,2,3}
// 可以省略长度,采用... 的方式。go会根据元素来确定数组长度。
c := [...]int{4,5,6}

嵌套数组

//声明一个二维数组,这个数组有两个元素,每个元素又是由4个int类型元素组成
doubleArray := [2][4]int{[4]int{1,2,3,4}, [4]int{5,6,7,8}}
//嵌套数组的简化声明。
easyArray := [2][4]int{{1,2,3,4}, {5,6,7,8}}

SLICE

slice 不是真正意义上的动态数组,是一个引用类型。
slice 总是指向一个底层 array slice 的声明和array一样,只是 不需要长度

命令: var sli []int
赋值: slice := []bypt{'a', 'b','c'}

slice 可以从一个数组或是一个已经存在的 slice 中再次声明。 slice 通过 array[i:j]来获取,其中i是数组的开始位置,j 是结束位置。但是不包括 j他的长度是j-i

var ar = [10]int{1,2,3,4,5,6,7,8,9,0}
// 声明两个含有 int 的slice
var a, b []int
// a 含有的元素是 ar[2] ar[3] ar[4]
a = ar[2:5]
// b 含有的元素是 ar[3] ar[4]
b = ar[3:5]

slice 的默认开始位置是 0 , ar[:n] 等价于 ar [0:n]
slice 的第二个序列默认是数组的长度,ar[n:] 等价于 ar[n:len(ar)]
如果从一个数组之间获取slice,可以写为: ar[:]

slicearray 的区别:声明数组时,方括号内写明了数组的长度或是使用 ...自动计算长度。
声明slice的时候,方括号内没有任何的字符
简单操作

var array = [10]byte{'a','b','c','d','e','f','g','h','i','j'}

var aslice, bslice []byte

aslice = array[:3]  //
aslice = array[5:]  //
aslice = array[:]   //

aslice = array[3:7]   // 包含了 d,e,f,g len=4 cap=7 
bslice = aslice[1:3]  // aslice[1] aslice[2]
bslice = aslice[:3]   // aslice[0] aslice[1] aslice[2]
bslice = aslice[0:5]  // aslice可以在cap范围内扩展。所以结果是:d,e,f,g,h
bslice = aslice[:]    // 包含了aslice所有元素

从概念上说,slice 像一个结构体,它包含了三个元素。

一个指针,指向了数组中slice开始的位置。
长度: slice的长度
最大长度: 也就是slice开始位置到数组的最后位置的长度,即cap
// 如上例,这里aslice的len=4,bslice这里取了5个元素,所以aslice要在cap的范围内扩展
bslice = aslice[0:5] 

slice 的内置函数

len 获取 slice 的长度
cap 获取 slice 的最大长度
append 向 slice 里追加一个或多个元素。
copy 从源 slice 的 src 中复制元素到目标,并返回复制元素的 个数。

注意:

append 会改变 slice 所引用数组的内容,从而影响到引用统一数组的其他slice
当slice 没有剩余空间(cap-len==0) 这时将动态分配新的数组空间。
返回的slice数组指针将指向新的空间。原数组的内容将保持不变。其他引用此数组的slice不受影响。

map

map 字典 格式 map[keyTpye]valueTpye
map 通过key 来操作。key有很多类型,可以是int,也可以是string 以及所有定义了 ==!=操作的类型。

var number map[string]int
// 另外一种声明方式
numbers := make(map[string]int)
numbers["one"] = 1
numbers["two"] = 2
numbers["three"] = 3

fmt.Printf("第二个数是: ",numbers["two"])

注意

map 是无序的,不是通过 index 获取,是通过 key 获取
map 的长度不固定。也是一种引用类型,和slice一样。
内置的len 适用于map。其作用是返回 map 中key的数量。
map 的值可以修改。例如numbers["ont"] = 12 就把one的字典值改成了11
map 初始化可以通过 key:val 的方式初始化,同时map内置有判断是否存在key的方式。
*** map 不是 three-safe,才多个goroutine存取的是,必须使用 mutex lock 机制。

map 的删除

rating := map[string]float32{"C":5, "Go":4.5, "Python":4.5, "C++":2}
// map 有两个返回值,第二个返回值,如果不存在key,则ok是false,如果存在,ok是true
csharpRating, ok := rating["C#"]
if ok {
    fmt.Println("C# is in the map and ist rating is ", csharpRating)    
} else {
    fmt.Println("We have no rating associated with C# in the map")
}
// 删除 key 为C的元素
delete(rating, "C")
// 打印字典
fmt.Println(rating)

make new

make 用于内建类型(map slice channel)的内存分配。
new 用于各种类型的内存分配。
new(T) 分配了零值填充的 T 类型的内存空间,并返回其地址,即一个*T 类型的值。 new 返回了一个指针
make(T, args) 和new有不同的功能,其返回一个有初始值的 T 类型。这是因为指向数据结构的引用在使用前必须被初始化。make 初始化了内部数据结构,填充适当的值,make 返回了一个初始化后的值(非零)
关于“零值” 并不是 空值。 是一种 变量未赋值前的默认值,通常为0

# 这里列出了部分类型的 零值
int     0
int8    0
int32   0
int64   0
uint    0x0
rune    0 //rune的实际类型是 int32
byte    0x0 // byte的实际类型是 uint8
float32 0 //长度为 4 byte
float64 0 //长度为 8 byte
bool    false
string  ""
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值