1.數組
go語言中也配有數組這種資料結構,它的定義方式類似
java
,每一種定義都是一種類型,比如:
var arr [50]int
和
var 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++中的引用,隻是把底層數組(原數組)某段位址拷貝過去了,并沒有建立新的數組。
定義方式:
- 直接定義,類似python的清單切片
- 借助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))
}