go语言的数组和切片的区别
数组和切片的理解
我们可以把切片看做是对数组的一层简单的封装,因为在每个切片的底层数据结构中,一定会包含一个数组。
数组可以被叫做切片的底层数组,而切片也可以被看作是对数组的某个连续片段的引用。切片代表的窗口也会被划分成一个一个的小格子,就像我们家里的窗户那样。每个小格子都对应着其底层数组中的某一个元素。
这个数组就是切片slice的底层数组,而这个窗口就是切片slice本身。slice的长度实际上指明的就是这个窗户的宽度,
决定了你透过slice,可以看到其底层数组中的哪几个连续的元素。
使用一个for循环来演示两者的区别
package main
import (
"fmt"
"reflect"
)
func main() {
fmt.Println("slice test 1")
sliceTest := []int{1, 2, 3, 4, 5, 6}
for i := range sliceTest {
if i == 2 {
sliceTest[i] |= i
fmt.Println(i, "i type", reflect.TypeOf(i))
}
//fmt.Println(i)
}
//string test
fmt.Println("string test")
stringTest := [6]int{1, 2, 3, 4, 5, 6}
maxItem := len(stringTest) - 1
for j, test2 := range stringTest {
if j == maxItem {
stringTest[0] += test2
fmt.Println("maxItem", maxItem, "j", j, "test2", test2)
fmt.Println("test2 type", reflect.TypeOf(test2))
fmt.Printf("Printf stringTest test2 type %T\n", test2)
} else {
fmt.Println("strBefor", stringTest)
stringTest[j+1] += test2
//这里test2只是执行range时stringTest的一个副本。
//在循环中test2不会随着stringTest内容的变化而变化
fmt.Println("test2 value", test2)
fmt.Println("strAfter", stringTest)
fmt.Println("~~~~~~~~~~~")
}
}
//fmt.Println(test2)
fmt.Println(stringTest)
//slice test 2
fmt.Println("slice test 2")
sliceTest2 := []int{0, 2, 3, 4, 5, 6}
maxItem2 := len(sliceTest2) - 1
for j, windowsToString := range sliceTest2 {
if j == maxItem2 {
sliceTest2[0] += windowsToString
fmt.Println("maxItem2", maxItem2, "j", j, "windowsToString", windowsToString)
fmt.Println("windowsToString type", reflect.TypeOf(windowsToString))
fmt.Printf("Printf sliceTest windowsToString type %T\n", windowsToString)
} else {
fmt.Println("sBefor", sliceTest2)
//这里windowsToString执行range后对sliceTest2的一个新的切片副本。
//就像是新开了一扇窗户(windowsToString),透过这扇窗户
//可以看到对面窗户(sliceTest2)里的风景(数组)。
sliceTest2[j+1] += windowsToString
fmt.Println("windowsToString value", windowsToString)
fmt.Println("sAfter", sliceTest2)
fmt.Println("###################")
}
}
fmt.Println(sliceTest2)
}
运行结果:
Printf stringTest test2 type int
[7 3 5 7 9 11]
slice test 2
sBefor [0 2 3 4 5 6]
windowsToString value 0
sAfter [0 2 3 4 5 6]
sBefor [0 2 3 4 5 6]
windowsToString value 2
sAfter [0 2 5 4 5 6]
sBefor [0 2 5 4 5 6]
windowsToString value 5
sAfter [0 2 5 9 5 6]
sBefor [0 2 5 9 5 6]
windowsToString value 9
sAfter [0 2 5 9 14 6]
sBefor [0 2 5 9 14 6]
windowsToString value 14
sAfter [0 2 5 9 14 20]
maxItem2 5 j 5 windowsToString 20
windowsToString type int
Printf sliceTest windowsToString type int
[20 2 5 9 14 20]