go——數組


數組(array)就是由若干個相同類型的元素組成的序列。

var ipv4 [4]uint8 = [4]uint8(192,168,0,1)

在這條賦值語句中,我們為剛聲明的變量ipv4賦值。在這種情況下,變量名右邊的類型字面量可以省略。
如果它在函數里面,那么關鍵字var也可以省略,但賦值符號必須由=變為:=。

類型字面量[4]uint8表明這個變量的類型長度為4且元素類型為uint的數組類型。
注意,數組的長度是數組類型的一部分。
只要類型聲明中的數組長度不同,即兩個數組類型的元素類型相同,它們也是不同的類型。
更重要的是,一旦在聲明中確定了數組類型的長度,就無法改變它了。
同時,同一類型的數組可以使用操作符==、!=。

package main

import "fmt"

var d0 [2]int //d0是數組類型的變量,因此也要遵循變量使用原則,全局變量可以只定義不使用,但是局部變量不行。

func main() {
	var d1 [3]int
	var d2 [2]int
	fmt.Println(d1 == d2) //invalid operation: d1 == d2 (mismatched types [3]int and [2]int)長度不同

	d3 := [2]int{1, 2}
	d4 := [2]int{2, 3}
	fmt.Println(d3 != d4) //true
	
}

 

數組初始化的方式比較靈活。
數組類型的零值一定是一個不包含任何元素的空數組。
一個類型的零值即為該類型變量未被顯式賦值時的默認值。

package main

import "fmt"

func main() {
	var a [3]int

	b := [4]int{2, 3}

	c := [4]int{5, 3: 10}

	d := [...]int{1, 2, 3}

	e := [...]int{3, 4, 4: 9}

	fmt.Println(a) //[0 0 0]      int類型的元素默認值為0
	fmt.Println(b) //[2 3 0 0]    位提供初始化的元素自動使用默認值
	fmt.Println(c) //[5 0 0 10]   3:10表示元素10是數組的第4個元素
	fmt.Println(d) //[1 2 3]      省略長度,但不是沒有,編譯器按照初始化元素的數量確定長度
	fmt.Println(e) //[3 4 0 0 9]

}

 

對於結構等復雜類型,可省略元素初始化類型標簽。

package main

import "fmt"

func main() {
	type user struct {
		name string
		age  int
	}

	d := [...]user{
		{"kebi", 26},    //省略類型標簽
		{"maoxian", 24},
	}

	fmt.Println(d)  //[{kebi 26} {maoxian 24}]
}

 

在定義多維數組時,僅第一維數組可以使用"..."。
內置函數len和cap都只能返回第一維度的長度。

package main

import "fmt"

func main() {
	a := [2][3]int{
		{1, 2, 3},
		{4, 5},
	}

	b := [...][2]int{
		{4, 2},
		{3, 4},
	}

	fmt.Println(a, len(a), cap(a))
	fmt.Println(b, len(b), cap(b))
}

/*
[[1 2 3] [4 5 0]] 2 2
[[4 2] [3 4]] 2 2
*/

 

要注意區分指針數組和數組指針。
指針數組:元素為指針類型的數組;數組指針:獲取數組變量的指針。

package main

import "fmt"

func main() {
	a := [...]int{1, 2, 3}
	fmt.Println(&a)           //數組沒有指針,只有數組的元素才有指針,數組只是對底層元素的包裝
	fmt.Println(&a[0], &a[1]) //數組指針 0xc00004c0c0 0xc00004c0c8

	x, y := 10, 20
	b := [2]*int{&x, &y}  //指針數組
	fmt.Println(b)  [0xc00004c0c0 0xc00004c0c8]
}

 

通過指針可以反取數據。

package main

import "fmt"

func main() {
	a := [2]int{1, 2}
	p := &a
	fmt.Println(*p) //[1 2]
}

 

Go數組是值類型,復制和傳參都會復制整個數組。
數組的指針是數組中第一個元素的指針。
數組是內層中某個連續的片段,復制和賦值都會在此分配片段,這屬於值復制,指針也不同。

package main

import "fmt"

func test(x [2]int) {
	fmt.Printf("x: %p, %v\n", &x, x)
}

func main() {
	a := [2]int{10, 20}
	var b [2]int
	b = a //復制

	fmt.Printf("a: %p, %v\n", &a, a) //a: 0xc00004e080, [10 20]
	fmt.Printf("b: %p, %v\n", &b, b) //b: 0xc00004e090, [10 20]
	test(a)                          //傳參//x: 0xc00004e0f0, [10 20]
	fmt.Println(&a[0], &a[1])        //0xc00004e080 0xc00004e088
	fmt.Println(&b[0], &b[1])        //0xc00004e090 0xc00004e098
}

 

如果需要,可改用指針或切片,這樣就可以避免復制,以此可以減少資源的消耗。

package main

import "fmt"

func test(x *[2]int) {  
	fmt.Printf("x: %p, %v\n", x, *x)
}

func main() {
	a := [2]int{10, 20}
	test(&a)  //直接傳遞的是指針,這樣就避免復制

	fmt.Printf("a: %p, %v\n", &a, a)
}

/*
x: 0xc00004e080, [10 20]
a: 0xc00004e080, [10 20]
*/

當需要詳細規划程序所用的內存時,數組類型非常有用。
使用數組值可以完全避免耗時費力的內存二次分配操作,因為它的長度是不可改變的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM