目录
array
声明数组
array由 数组的索引从 0 开始到 length - 1 结束。数组中的所有元素都被自动赋值为数组类型的零值。文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
NOTE 数组的大小是类型的一部分.文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
由于长度也是数组类型的一部分,因此 [3]int 与 [4]int 是不同的类型,数组也就不能改变长度。文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
Go 中的数组是值类型而不是引用类型。文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
数组之间的赋值是值的赋值,即当把一个数组作为参数传入函数的时候,传入的其实是该数组的副本,而不是它的指针。 初始化数组中 {} 中的元素个数不能大于 [] 中的数字。 初始化数组时,可以只初始化部分数组的值,例:文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
slice 与 array 接近,但是在新的元素加入的时候可以增加长度.slice 是一个指向 array 的指针,这是其与 array 不同的地方; 例:文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
上述执行输出结果为:文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
函数 注 例:文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
一般定义 map 的方法是:文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
例:文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
当只需要声明一个 map 的时候,使用 make 的形式:monthdays := make(map[string]int) 当在 map 中索引(搜索)时,使用方括号。 使用map过程中需要注意的几点:文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
例:文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
输出结果: 例2:文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
map 也是一种引用类型,如果两个 map 同时指向一个底层,那么一个改变,另一个也相应的改变:文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
例文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
[n]<type>
定义,n为array的长度,var arr [10]int //声明一个int类型的数组
arr[0] = 42 //数组下标是从0开始的
arr[1] = 13 //赋值操作
如果要使用指针,那么就需要用到后面介绍的 slice
类型了。文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
初始化数组
a := [3]int{1, 2, 3}
如果忽略 [] 中的数字不设置数组大小,Go 语言会根据元素的个数来设置数组的大小:文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
a := [...]int{1, 2, 3}
b := [10]int{1, 2, 3} //声明了一个长度为10的int数组,其中前3个元素初始化为1、2、3,其他默认为0。
二维数组
package main
import "fmt"
func main() {
a := [2][2]int{ [2]int{1, 2}, [2]int{3, 4} }
fmt.Println(a)
b := [2][3] int { {1, 2, 3}, {2, 2, 3}}
fmt.Println(b) //[[1 2 3] [2 2 3]]
c := [2][2]int{[...]int{1, 2}, [...]int{3, 4} }
fmt.Println(c)
}
slice
slice 是引用类型,这意味着当赋值某个 slice 到另外一个变量,两个引用会指向同一个 array.文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
创建切片
基于数组创建
package main
import "fmt"
func main() {
//定义一个 5 个元素的 array,序号从 0 到 4
a := [...]int{1, 2, 3, 4, 5}
fmt.Println("array a is:", a)
//从序号 2 至 3 创建 slice,它包含元素 3, 4 , s1 := a[0:6]; 编译时会报错。因为超出了数组范围
s1 := a[2:4]
fmt.Println("slice s1 is:", s1)
//从序号 1 至 4 创建,它包含元素 2, 3, 4, 5
s2 := a[1:5]
fmt.Println("slice s2 is:", s2)
//用 array 中的所有元素创建 slice,这是 a[0:len(a)] 的简化写法
s3 := a[:]
fmt.Println("slice s3 is:", s3)
//从序号 0 至 3 创建,这是 a[0:4] 的简化写法,得到 1, 2, 3, 4
s4 := a[:4]
fmt.Println("slice s4 is:", s4)
//从 slice s2 创建 slice,注意 s5 仍然指向 array a。a的值变了,slice的值也随之改变
s5 := s2[:]
fmt.Println("slice s5 is:", s5)
fmt.Println("-----------------")
s2[0] = 1
fmt.Println("array a is:", a)
fmt.Println("slice s1 is:", s1)
fmt.Println("slice s2 is:", s2)
fmt.Println("slice s3 is:", s3)
fmt.Println("slice s4 is:", s4)
fmt.Println("slice s5 is:", s5)
}
array a is: [1 2 3 4 5]
slice s1 is: [3 4]
slice s2 is: [2 3 4 5]
slice s3 is: [1 2 3 4 5]
slice s4 is: [1 2 3 4]
slice s5 is: [2 3 4 5]
-----------------
array a is: [1 1 3 4 5]
slice s1 is: [3 4]
slice s2 is: [1 3 4 5]
slice s3 is: [1 1 3 4 5]
slice s4 is: [1 1 3 4]
slice s5 is: [1 3 4 5]
直接创建
mySlice1 := make([]int, 5)
mySlice2 := make([]int, 5, 10)
mySlice3 := []int{1, 2, 3, 4, 5}
slice 和 array 在声明时的区别
...
自动计算长度// 声明一个含有10个元素元素类型为byte的数组
var ar = [10]byte {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
// 声明两个含有byte的slice
var a, b []byte
// a指向数组的第3个元素开始,并到第五个元素结束,
a = ar[2:5]
//现在a含有的元素: ar[2]、ar[3]和ar[4]
// b是数组ar的另一个slice
b = ar[3:5]
// b的元素是:ar[3]和ar[4]
slice的一些简便操作
操作 slice 几个有用的内置函数
len
获取 slice 的长度。cap
获取slice的最大容量。append
向 slice 里面追加一个或者多个元素,然后返回一个和 slice 一样类型的 slice。copy
函数 copy 从源 slice 的 src 中复制元素到目标 dst,并且返回复制的元素的个数。copy
从源 slice src 复制元素到目标 dst,并且返回复制的元素的个数。源和目标可能重叠。复制的数量是 len(src) 和 len(dst) 中的最小值。文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
append 函数会改变 slice 所引用的数组的内容,从而影响到引用同一数组的其它 slice。 但当 slice 中没有剩余空间(即(cap - len) == 0)时,此时将动态分配新的数组空间。返回的 slice 数组指针将指向这个空间,而原数组的内容将保持不变;其它引用此数组的 slice 则不受影响。文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
package main
import "fmt"
func main(){
arr := [10]int{1, 2, 3, 4, 5}
s1 := arr[0:2]
fmt.Println(len(s1)) //输出2
fmt.Println(cap(s1)) //输出10
}
map
声明 map
map[<from type>] <to type>
var numbers map[string] int
numbers := make(map[string] int)
例:文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
package main
import "fmt"
func main(){
monthdays := map[string]int{
"Jan": 31, "Feb": 28, "Mar": 31,
"Apr": 30, "May": 31, "Jun": 30,
"Jul": 31, "Aug": 31, "Sep": 30,
"Oct": 31, "Nov": 30, "Dec": 31,//此处的逗号是必须的
}
for key, val := range monthdays {
fmt.Printf("key = %s, val = %d\n", key, val)
}
}
例如打印出 12 月的天数:fmt.Printf("%d\n", monthdays["Dec"])
这个map就像我们平常看到的表格一样,左边列是 key ,右边列是值文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
Thread-safe
,在多个 goroutine 存取时,必须使用 mutex lock 机制。 Go1.9 以后可用 sync.Map
解决这个问题key:val
的方式初始化值,同时 map 内置有判断是否存在 key 的方式通过 delete 删除 map 的元素
package main
func main() {
monthdays := map[string]int{
"Jan": 31, "Feb": 28, "Mar": 31,
"Apr": 30, "May": 31, "Jun": 30,
"Jul": 31, "Aug": 31, "Sep": 30,
"Oct": 31, "Nov": 30, "Dec": 31,
}
//删除map中Feb元素
delete(monthdays, "Feb")
//map 有两个返回值,第一个返回值为该 key 的值;
// 第二个返回值,如果不存在 key,那么 ok 为 false,如果存在 ok 为 true
val, ok := monthdays["Feb"]
//判断monthdays["Feb"]是否存在
if ok {
println("Feb is in the map and its value is", val)
} else {
println("Feb isn't in the map")
}
}
Feb isn't in the map文章源自编程技术分享-https://mervyn.life/d9deb1b5.html
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var ms = map[string]Vertex{
"Bell Labs": {40.68433, -74.39967},
"Google": {37.42202, -122.08408},
}
func main() {
fmt.Println(ms)
}
文章源自编程技术分享-https://mervyn.life/d9deb1b5.html package main
import "fmt"
func main() {
m := make(map[string]string)
fmt.Println("map m is: ", m)
m["Hello"] = "Bonjour"
m["World"] = "XXXXX"
fmt.Println("map m is: ", m)
m1 := m
fmt.Println("map m1 is: ", m1)
m1["Hello"] = "Salut" // 现在m["hello"]的值已经是Salut了
fmt.Println("map m is: ", m)
fmt.Println("map m1 is: ", m1)
}
评论