天天看點

go語言的數組和切片的差別

go語言的數組和切片的差別

    • 數組和切片的了解
    • 使用一個for循環來示範兩者的差別

數組和切片的了解

我們可以把切片看做是對數組的一層簡單的封裝,因為在每個切片的底層資料結構中,一定會包含一個數組。

數組可以被叫做切片的底層數組,而切片也可以被看作是對數組的某個連續片段的引用。切片代表的視窗也會被劃分成一個一個的小格子,就像我們家裡的窗戶那樣。每個小格子都對應着其底層數組中的某一個元素。

這個數組就是切片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]