天天看点

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]