【go語言學習筆記】數組和切片

1.數組

go語言中也配有數組這種數據結構,它的定義方式類似java,每一種定義都是一種類型,比如:
var arr [50]intvar arr [100]int,他們分別是[50]int類型和[100]int類型。

可以使用迭代器來遍歷數組。

demo:

package main

import "fmt"

func main() {
	// 數組,同一個類型的集合
	var arr [50]int

	//操作數組,通過下標,從0開始到len-1

	// 一般for循環寫法
	for i := 0; i < len(arr); i++ {
		arr[i] = i * 2
		fmt.Println(arr[i])
	}

	//迭代器寫法
	for i := range arr {
		arr[i] = i
	}

	for i := range arr {
		fmt.Println(arr[i])
	}
}


2.二維數組

定義方式同上。
demo:

package main

import "fmt"

func main() {
	// 二維數組
	var a [3][4]int

	fmt.Println("a = ", a)
}

3.切片的創建

切片的底層是結構體,這裏的切片類似c++中的引用,只是把底層數組(原數組)某段地址拷貝過去了,並沒有創建新的數組。

定義方式:

  1. 直接定義,類似python的列表切片
  2. 藉助make函數,make(切片類型,長度,容量)
package main

import "fmt"

func main() {
	//自動推導類型,同時初始化
	s1 := []int{1, 2, 3, 4}
	fmt.Println("s1 = ", s1)

	//藉助make函數, make(切片類型,長度, 容量)
	s2 := make([]int, 5, 10)
	fmt.Println("len = ", len(s2), "cap = ", cap(s2))
	//沒有指定容量,容量和長度一樣
	s3 := make([]int, 5)
	fmt.Println("len = ", len(s3), "cap = ", cap(s3))
}

4.切片的截取

這裏的截取類似python的切片,也是得到原數組的地址引用。

package main

import "fmt"

func main() {
	arr := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	//[low:high:max] 取下標從low開始至high-1的元素
	s1 := arr[:] //取整個數組
	fmt.Println("s1 = ", s1)

}


5.切片和數組的區別

數組[]裏面的長度是一個固定常量,數組不能修改長度,len和cap固定,而切片,[]裏面爲空,或者…,切片的長度或容量可以不確定。
直接定義的切片像是動態擴容數組的替代品。

package main

import "fmt"

func main() {
	//切片和數組的區別
	//數組[]裏面的長度是一個固定常量,數組不能修改長度,len和cap固定
	a := [5]int{}
	fmt.Println("len = ", len(a), " cap = ", cap(a))

	//切片,[]裏面爲空,或者...,切片的長度或容量可以不確定
	b := []int{}
	fmt.Println("len = ", len(b), "cap = ", cap(b))

	b = append(b, 11)
	fmt.Println("len = ", len(b), "cap = ", cap(b))

}


6.切片做函數參數

這樣傳入的切片像是引用傳遞,而不是數組的值傳遞,這樣可以提高效率,節約內存。

package main

import "fmt"
import "math/rand"
import "time"

func InitData(s []int) {
	//設置隨機種子
	rand.Seed(time.Now().UnixNano())

	for i := 0; i < len(s); i++ {
		s[i] = rand.Intn(100)
	}
}

func BubbleSort(s []int) { //傳入一個數組的引用,,相當於傳指針
	n := len(s)

	for i := 0; i < n-1; i++ {
		for j := 0; j < n-i-1; j++ {
			if s[j] > s[j+1] {
				s[j], s[j+1] = s[j+1], s[j]
			}
		}
	}
}

func main() {
	n := 10

	// 創建一個切片,len = n
	s := make([]int, n)

	InitData(s) //初始化數組
	BubbleSort(s)
	fmt.Println("s = ", s)
}


7.數組的比較和賦值

go語言支持數組的比較和賦值,但只支持==!=,他會逐個比較每個元素是否值一樣,並且數組類型要相同才能比較和賦值,比如[50]int類型和[100]int類型就不能比較和賦值,因爲他們不是同一個類型。

package main

import "fmt"

func main() {
	// 支持比較,只支持 == 或 !=, 比較是不是每一個元素都一樣,2個數組比較,數組類型要一樣
	// 比如 [5]int 和 [6]int就不是一個類型

	a := [5]int{1, 2, 3, 4, 5}
	b := [5]int{1, 2, 3, 4, 5}
	c := [5]int{1, 2, 3}
	fmt.Println("a == b", a == b)
	fmt.Println("a == c", a == c)

	// 同類型的數組可以賦值
	var d [5]int
	d = a
	fmt.Println("d = ", d)

	// 自動推導長度
	e := [...]int{1, 2, 3, 4}
	fmt.Println("e = ", e, "len(e) = ", len(e))
}


8.數組的初始化

這裏的初始化類似c語言中的初始化,並加入了指定位置初始化,若是隻初始化部分元素,未顯式初始化的其他元素都會被初始化爲0。

package main

import "fmt"

func main() {
	//1. 全部初始化
	var a [5]int = [5]int{1, 2, 3, 4, 5}
	fmt.Println("a = ", a)

	b := [6]int{1, 2, 3, 4, 5, 6}
	fmt.Println("b = ", b)

	//2. 部分初始化,沒有初始化的元素自動賦值爲0
	c := [5]int{1, 2, 3}
	fmt.Println("c = ", c)

	//3. 指定元素初始化
	d := [5]int{2: 3, 4: 6}
	fmt.Println("d = ", d)
}


9.數組的切片

數組切片 [low:high:max],是原數組的引用,其中的參數意義如下

  • low: 下標的起點
  • high: 下標的終點,不包括該下標,左閉右開
  • max:爲切片保留的原切片的最大下標(不含max)
  • cap : max - low 容量,因爲切片是原數組的引用,所以用max減去起始的指針,就是引用數組的容量。
package main

import "fmt"

func main() {
	a := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 10}

	//數組切片 [low:high:max],是原數組的引用
	// low: 下標的起點
	// high: 下標的終點,不包括該下標,左閉右開
	// max:爲切片保留的原切片的最大下標(不含max)
	// cap : max - low 容量,因爲切片是原數組的引用,所以用max減去起始的指針,就是引用數組的容量
	slice := a[1:3:5]

	fmt.Println("slice = ", slice)
	fmt.Println("len(slice) = ", len(slice))
	fmt.Println("cap(slice) = ", cap(slice))
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章