曾经学习python
的时候,记得书上说 dict 是 python
的 horsepower(动力)。然后,Slice 和 Map 又何尝不是 golang
的 workhorse 呢?
数组的声明(这里就是定义,给数据存储分配了空间):
var arrayName [arraySize] dataType
如果数组定义好之后, 没有给数组元素指定值,那么所有元素被自动初始化为零值。
var a = [10]int {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} //定义数组的时候,直接初始化
var b = [10]int {1, 2, 3, 4} //部分元素初始化, 其余元素零值
var c = [...]int {1, 2, 3, 4, 5} //由初始化列表决定数组长度,不可省去标识符 "...",否则将变成切片Slice
var d = [10]{2:4, 5:7} //可以按照下标来进行初始化
package main
import(
"fmt"
)
func main() {
var f = [20]int {1, 1}
for i := 2; i < 20; i++ {
f[i] = f[i-1] + f[i-2]
}
for i := 0; i < 20; i++ { //采用下标进行遍历
if i % 5 == 0 {
fmt.Printf("\n")
}
fmt.Printf("f[%2d] = %4d",i , f[i])
}
}
也可以采用 range 关键字进行遍历:
func main() {
var f = [20]int {1, 1}
for i := 2; i < 20; i++ {
f[i] = f[i-1] + f[i -2]
}
for i , v := range f { //采用 range 关键字 进行遍历
fmt.Printf("f[%2d] = %4d", i, v)
}
}
var a [3][4]int
var a = [3][4]int {{1,2}, {1,2,3,4}, {2,3, 4}}
/*找到二维数组中的最大元素*/
package main
import "fmt"
func main() {
var i, j, row, col, max int
var a = [3][4]int {{1, 3, 7, 3}, {2, 3, 7 , 9}, {22, 3, 5, 10}}
max = a[0][0]
for i := 0; i < = 2; i ++ {
for j := 0; j <= 3; j++ {
if a[i][j] > max {
max = a[i][j]
row = i
col = j
}
}
}
fmt.Println("max = %d, row = %d, col = %d\n", max, row, col)
}
`var s1 []int`
len()
获得切片的长度,使用内建函数 cap()
获得切片的容量。三种创建方式: 基于底层数组创建,直接创建,或者 make() 函数创建
var slice1 []int //声明但是不分配空间
slice1 = array[start:end] //这里不包含 end
slice2 := array[:] // 引用全部的元素
slice3 := array[0:len(array)]
var slice4 []int
sliec34 = array //引用全部的元素
在声明的时候,直接初始化。
var slice1 = []int {1 ,2, 3, 4, 5}
make()
函数创建 slicevar slice1 = make([]int, 5) //长度和容量都是 5
var slice2 = make([]int, 5, 10) //容量是5.
采用下标进行访问,采用 range 进行遍历。
packge main
import "fmt"
func main() {
var slice1 = []int {1, 2,3 , 4, 5}
//使用下标访问 slice
for i := 0; i <=4; i++ {
fmt.Println("slice[%d] = %d", i, slice[i])
}
fmt.Println()
//使用range 进行遍历
for i, v := range slice {
fmt.Println("slice[%d] = %d", i, v)
}
}
Slice 中的切片的元素,可以动态的添加和删除,所以操作起来要比数组更加方便。
采用内建函数 append()
向切片尾部,增加新的元素, 这些元素保存到底层的数组。
package main
import "fmt"
func main() {
//使用make 创建 切片
var slice1 = make([]int, 3, 6)
// 使用 append 添加元素,并且未超出 cap
slice2 := append(slice1, 1, 2, 3)
// 使用 append 添加元素,并且超出 cap. 这个时候底层数组会变化,新增加的元素只会添加到新的底层数组,不会覆盖旧的底层数组。
slice3 := append(slice1, 4, 5, 6, 7)
slice1[0] = 10
fmt.Printf("len = %d cap = %d %v\n", len(slice1), cap(slice1), slice1)
fmt.Printf("len = %d cap = %d %v\n", len(slice2), cap(slice2), slice2)
fmt.Printf("len = %d cap = %d %v\n", len(slice3), cap(slice3), slice3)
}
程序输出是:
len = 3 cap = 6 [10 0 0]
len = 6 cap = 6 [10 0 0 1 2 3] // 这里的[1, 2, 3] 没有被 [4, 5, 6]覆盖
len = 7 cap = 12 [0 0 0 4 5 6 7] //这里第一个元素没有变成10,并且容量变成原来的2倍。
使用切片长时间引用超大的底层数组,会导致严重的内存浪费现象。 可以新建一个小的slice 对象,然后将所需要的数据复制过去,这样子就不会引用底层数组,直接拷贝了数据,这就是需求。函数 copy()可以 在切片之间复制元素。
package main
import "fmt"
func main() {
var slice1 = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
var slice2 = make([]int, 3, 5)
var n int
n = copy(slice2, slice1) // just copy three elements
fmt.Println(n, slice2, len(slice2), cap(slice2))
slice3 := slice1[3:6] //二者引用同一个底层数组
n = copy(slice3, slice1[1:5]) //所以,copy的时候发生元素重叠
fmt.Println(n, slice1, slice3)
}
程序输出为:
3 [1 2 3] 3 5
3 [1 2 3 2 3 4 7 8 9 10] [2 3 4] //可以看到元素重叠
map 存储的是 键值对(key-value)。是一个无序的数据的集合,通过键来进行索引得到对应的值。 这种方式可以加快查找速度。Map 通常称为 字典(dictionary) 或者哈希表(Hash table)。Map 现在是很多语言的标配。
字典名称,“键”类型, “值”类型
var mapName map[keyType]valueType
注意:
var map1 map[string]int
make()
来创建字典。“=”
操作符来动态的向字典中添加数据项了。 var map1 map[string]int
map1["key1"] = 2 //编译不通过,字典没有初始化或者创建
下面使用方式正确
var map1 map[string]int {} //字典的初始化
map1["key1"] = 1
var map2 map[string]int
map2 = make(map[string]int) //字典的创建
map2["key2"] = 2 //使用 等号 添加数据项
v, OK := mapName[Key] //注意这里是 :=
如果Key存在,将Key对应的Value赋值给v,OK== true. 否则 v 是0,OK==false.
package main
import "fmt"
func main() {
var map1 = map[string]int{"key1": 100, "key2": 200}
//
v, OK := map1["key1"]
if OK {
fmt.Println(v, OK)
} else {
fmt.Println(v)
}
// 这里 不是 :=,是 = ,因为这些变量已经定义过了。
v, OK = map1["key3"]
if OK {
fmt.Println(v, OK)
} else {
fmt.Println(v)
}
}
输出为:
100 true
0
go 提供了内置函数 delete()
来删除容器内的元素。
delete(map1, "key1")
如果key1值不存在,那么调用将什么也不发生,也不会产生副作用。 但是,如果传入的map 是一个 nil,那么将导致程序出现异常,这一点在写程序的时候特别注意。
package main
import (
"fmt"
)
func main() {
var map1 = map[string]int{"key1": 100, "key2": 200, "key3": 300}
for k, v := range map1 {
fmt.Println(k, v)
if k == "key2" {
delete(map1, k)
}
if k == "key3" {
map1["key4"] = 400
}
}
fmt.Println(map1)
}
程序输出:
key2 200
key3 300
key1 100
map[key1:100 key4:400 key3:300] //可以看到 map 是无序的。
原文:http://blog.csdn.net/xiaorenwuzyh/article/details/44564069