【数组】
Go语言处理数组特别的地方是:go把数组看成是值传递
如果需要传引用,需要额外处理 *[5]int
如下demo
package main
import (
"fmt"
)
func main() {
var arr1 = [5]int{1, 2, 3, 4, 5}
var arr2 = [5]int{1, 2, 3, 4, 5}
fmt.Println("arr1 is:", arr1)
dealarr(arr1)
fmt.Println("arr1 is:", arr1)
// *[5]int p
fmt.Println("arr2 is:", arr2)
dealp(&arr2) //通过& 来获取指针传递参数
fmt.Println("arr2 is:", arr2)
}
func dealarr(a [5]int) {
a[0] = 55
fmt.Println(" a is:", a)
}
func dealp(b *[5]int) {
b[0] = 66
fmt.Println("b is", b)
}
执行结果如下:
arr1 is: [1 2 3 4 5]
a is: [55 2 3 4 5]
arr1 is: [1 2 3 4 5]
arr2 is: [1 2 3 4 5]
b is &[66 2 3 4 5]
arr2 is: [66 2 3 4 5]
【slice】
slice的代码定义在runtime下的 slice.go中,其类型如下
type slice struct {
array unsafe.Pointer
len int
cap int
}
是一个有三个元素的struct
- array 为指针,指向数组的可以从slice中访问的第一个元素
- len 为长度,slice中元素的个数
- cap为容量,从slice的的起始元素(即指针)到底层数组最后一个元素间的个数
检测一个slice是否为空 使用len(slice1)==0.
更多demo如下
package main
import (
"fmt"
)
func main() {
var arr = [10]string{"a1", "b2", "c3", "d4", "e5", "f6", "g7", "h8", "i9", "j10"}
fmt.Printf("arr type is %T,\nvalue is %v\n", arr, arr)
fmt.Println("len(arr) is:", len(arr))
s1 := arr[1:1]
fmt.Println("s1: arr[1:1]", s1, "len is:", len(s1), "cap is:", cap(s1))
s2 := arr[2:5]
fmt.Println("s2: arr[2:5]", s2, "len is:", len(s2), "cap is:", cap(s2))
s3 := arr[5:]
fmt.Println("s3: arr[5:]", s3, "len is:", len(s3), "cap is:", cap(s3))
s4 := arr[:5]
fmt.Println("s4: arr[:5]", s4, "len is:", len(s4), "cap is:", cap(s4))
s5 := arr[:]
fmt.Println("s5: arr[:]", s5, "len is:", len(s5), "cap is:", cap(s5))
s6 := arr[7:8]
fmt.Println("s6: arr[7:8]", s6, "len is:", len(s6), "cap is:", cap(s6))
s7 := arr[2:8]
fmt.Println("s7 is: arr[2:8]", s7)
//使用 range 来遍历下标及value
for i, j := range s7 {
fmt.Println("i is", i, "j is:", j)
}
}
执行结果如下,可以体会出 len cap 及指针的实际意义。
arr type is [10]string,
value is [a1 b2 c3 d4 e5 f6 g7 h8 i9 j10]
len(arr) is: 10
s1: arr[1:1] [] len is: 0 cap is: 9
s2: arr[2:5] [c3 d4 e5] len is: 3 cap is: 8
s3: arr[5:] [f6 g7 h8 i9 j10] len is: 5 cap is: 5
s4: arr[:5] [a1 b2 c3 d4 e5] len is: 5 cap is: 10
s5: arr[:] [a1 b2 c3 d4 e5 f6 g7 h8 i9 j10] len is: 10 cap is: 10
s6: arr[7:8] [h8] len is: 1 cap is: 3
s7 is: arr[2:8] [c3 d4 e5 f6 g7 h8]
i is 0 j is: c3
i is 1 j is: d4
i is 2 j is: e5
i is 3 j is: f6
i is 4 j is: g7
i is 5 j is: h8
【数组与slice】
slice依赖一个底层的数组,下面的例子在同个底层数组上创建了2 个slice,分别通过更改数组的值,slice的值 来对比全局的数据变化,最后演示了 append()内置函数的调用demo,可以看到 在slice中append数据,在容量允许的情况下会修改底层数组的值。
package main
import (
"fmt"
)
func main() {
var arr1 = [10]string{"z0", "a1", "b2", "c3", "d4", "e5", "f6", "g7", "h8", "i9"}
slice1 := arr1[0:4]
slice2 := arr1[2:6]
//注意两个slice中的共同元素
//注意元素个数与切片数值的管理
fmt.Println("slice1 arr1[0:4]:", slice1)
fmt.Println("slice2 arr1[2:6]:", slice2)
//直接修改底层数组来看slice的变化
fmt.Println("arr1[2] is:", arr1[2])
arr1[2] = "BB22"
fmt.Println("arr1[2] is:", arr1[2])
fmt.Println("now arr1 is:", arr1)
fmt.Println("slice1 arr1[0:4]:", slice1)
fmt.Println("slice2 arr1[2:6]:", slice2)
//直接修改其中slice1的第四个元素
fmt.Println("slice1[3] is:", slice1[3])
slice1[3] = "Cnew"
fmt.Println("slice1[3] is:", slice1[3])
fmt.Println("### after change slice1[3]")
//修改slice1 后观察底层数组及 slice2的变化
fmt.Println("arr1 is:", arr1)
fmt.Println("slice1 arr1[0:4]:", slice1)
fmt.Println("slice2 arr1[2:6]:", slice2)
//append 对数据的影响
slicenew := append(slice1, "from_append")
fmt.Println("arr1 is:", arr1)
fmt.Println("slice1 arr1[0:4]:", slice1)
fmt.Println("slice2 arr1[2:6]:", slice2)
fmt.Println("slicenew is:", slicenew)
}
执行结果如下
slice1 arr1[0:4]: [z0 a1 b2 c3]
slice2 arr1[2:6]: [b2 c3 d4 e5]
arr1[2] is: b2
arr1[2] is: BB22
now arr1 is: [z0 a1 BB22 c3 d4 e5 f6 g7 h8 i9]
slice1 arr1[0:4]: [z0 a1 BB22 c3]
slice2 arr1[2:6]: [BB22 c3 d4 e5]
slice1[3] is: c3
slice1[3] is: Cnew
### after change slice1[3]
arr1 is: [z0 a1 BB22 Cnew d4 e5 f6 g7 h8 i9]
slice1 arr1[0:4]: [z0 a1 BB22 Cnew]
slice2 arr1[2:6]: [BB22 Cnew d4 e5]
arr1 is: [z0 a1 BB22 Cnew from_append e5 f6 g7 h8 i9]
slice1 arr1[0:4]: [z0 a1 BB22 Cnew]
slice2 arr1[2:6]: [BB22 Cnew from_append e5]
slicenew is: [z0 a1 BB22 Cnew from_append]