數組,切片


1、數組

數組屬於值類型。

1)聲明

var 數組變量名 [元素數量]Type

  • 數組變量名:數組聲明及使用時的變量名。
  • 元素數量:數組的元素數量,可以是一個表達式,但最終通過編譯期計算的結果必須是整型數值,元素數量不能含有到運行時才能確認大小的數值。
  • Type:可以是任意基本類型,包括數組本身,類型為數組本身時,可以實現多維數組。

默認情況下,數組的每個元素都會被初始化為元素類型對應的零值,對於數字類型來說就是 0,同時也可以使用數組字面值語法,用一組值來初始化數組。

在數組的定義中,如果在數組長度的位置出現“...”省略號,則表示數組的長度是根據初始化值的個數來計算。

示例:

package main

import "fmt"

func main() {
	var a [3]int
	for i := 0; i < len(a);  i++{
		fmt.Printf("%d, %d\n", i, a[i])
	}
	var b = [3]int{1, 2}
	fmt.Println("----------------------------")
	for i := 0; i < len(b);  i++{
		fmt.Printf("%d, %d\n", i, b[i])
	}
	c := [...]int{1, 2, 3}
	fmt.Println("----------------------------")
	for i := 0; i < len(c);  i++{
		fmt.Printf("%d, %d\n", i, c[i])
	}
}

  

2)比較兩個數組是否相等

如果兩個數組類型相同(包括數組的長度,數組中元素的類型)的情況下,我們可以直接通過較運算符(== 和!=)來判斷兩個數組是否相等,只有當兩個數組的所有元素都是相等的時候數組才是相等的,不能比較兩個類型不同的數組,否則程序將無法完成編譯。

數組類型相同的數組之間可以互相賦值。

 

3)多維數組

示例:

package main

import "fmt"

func output(str string, arr [4][2]int)  {
	fmt.Printf("ArrName: %s\n", str)
	for i := 0; i < 4; i++{
		for j := 0; j < 2 ; j++  {
			fmt.Printf("%d, ", arr[i][j])
		}
		fmt.Println()
	}
}

func main() {
	// 聲明一個二維整型數組,兩個維度的長度分別是 4 和 2
	var a [4][2]int
	output("a", a)
	// 使用數組字面量來聲明並初始化一個二維整型數組
	b := [4][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}}
	output("b", b)
	// 聲明並初始化數組中索引為 1 和 3 的元素
	c := [4][2]int{1: {20, 21}, 3: {40, 41}}
	output("c", c)
	// 聲明並初始化數組中指定的元素
	d := [4][2]int{1: {0: 20}, 3: {1: 41}}
	output("d", d)
}

  

 2、切片

切片(slice)是對數組的一個連續片段的引用,所以切片是一個引用類型。Go語言中切片的內部結構包含地址、大小和容量,切片一般用於快速地操作一塊數據集合。

1)從數組或切片生成新的切片

從連續內存區域生成切片是常見的操作,格式如下:

slice [開始位置 : 結束位置]

  • slice:表示目標切片對象;
  • 開始位置:對應目標切片對象的索引;
  • 結束位置:對應目標切片的結束索引。

從數組或切片生成新的切片擁有如下特性:

  • 取出的元素數量為:結束位置 - 開始位置;
  • 取出元素不包含結束位置對應的索引,切片最后一個元素使用 slice[len(slice)] 獲取;
  • 當缺省開始位置時,表示從連續區域開頭到結束位置;
  • 當缺省結束位置時,表示從開始位置到整個連續區域末尾;
  • 兩者同時缺省時,與切片本身等效;
  • 兩者同時為 0 時,等效於空切片,一般用於切片復位。

示例:

package main

import "fmt"

func main() {
	var a = [3]int{1,2,3}
	fmt.Println(a[1:2])
	fmt.Println(a[:3])
	fmt.Println(a[0:])
}

  

2)直接聲明切片

除了可以從原有的數組或者切片中生成切片外,也可以聲明一個新的切片,每一種類型都可以擁有其切片類型,表示多個相同類型元素的連續集合,因此切片類型也可以被聲明,切片類型聲明格式如下:

var name []Type

切片是動態結構,只能與 nil 判定相等,不能互相判定相等。

聲明新的切片后,可以使用 append() 函數向切片中添加元素。

示例:

package main

import "fmt"

func main() {
	var a []int // 聲明但未使用的切片的默認值是 nil
	var b = []int{} // 已經分配了內存
	fmt.Println(a == nil) // true
	fmt.Println(b == nil) // false
}

  

3)使用make()函數構造切片

如果需要動態地創建一個切片,可以使用 make() 內建函數,格式如下:

make( []Type, size, cap )

其中 Type 是指切片的元素類型,size 指的是為這個類型分配多少個元素,cap 為預分配的元素數量,這個值設定后不影響 size,只是能提前分配空間,降低多次分配空間造成的性能問題。

注意:使用 make() 函數生成的切片一定發生了內存分配操作,但給定開始與結束位置(包括切片復位)的切片只是將新的切片結構指向已經分配好的內存區域,設定開始與結束位置,不會發生內存分配操作。

示例:

package main

import "fmt"

func main() {
	a := make([]int, 2, 10)
	fmt.Println(a)
	fmt.Println("len=", len(a))
	fmt.Println("cap=", cap(a))
}

  

 4)添加元素

Go語言的內建函數 append() 可以為切片動態添加元素,在使用 append() 函數為切片動態添加元素時,如果空間不足以容納足夠多的元素,切片就會進行“擴容”,此時新切片的長度會發生改變。

尾部添加元素示例:

package main

import "fmt"

func main() {
	var a []int
	a = append(a, 1) // 追加1個元素
	a = append(a, 1, 2) // 追加多個元素
	a = append(a, []int{1, 2, 3}...) // 追加一個切片
	fmt.Println(a)
}

  

頭部添加元素示例:

package main

import "fmt"

func main() {
	var a = []int{1, 2, 3}
	a = append([]int{1}, a...) // 在開頭添加1個元素
	a = append([]int{1, 2}, a...) // 在開頭添加1個切片
	fmt.Println(a)
}

  

切片中間插入元素示例:

package main

import "fmt"

func main() {
	var a = []int{1, 2, 3, 4, 5}
	// 在第2個位置插入一個切片
	a = append(a[:2], append([]int{998, 999}, a[2:]...)...)
	/*
	每個添加操作中的第二個 append 調用都會創建一個臨時切片,並將 a[i:] 的內容復制到新創建的切片中,
	然后將臨時創建的切片再追加到 a[:i] 中。
	*/
	fmt.Println(a)
}

  

5)切片復制

Go語言的內置函數 copy() 可以將一個數組切片復制到另一個數組切片中,如果加入的兩個數組切片不一樣大,就會按照其中較小的那個數組切片的元素個數進行復制。

copy() 函數的使用格式:copy( destSlice, srcSlice []T) int

其中 srcSlice 為數據來源切片,destSlice 為復制的目標(也就是將 srcSlice 復制到 destSlice),來源和目標的類型必須一致,copy() 函數的返回值表示實際發生復制的元素個數。

示例:

package main

import "fmt"

func main() {
	slice1 := []int{1,2,3,4,5}
	slice2 := []int{100, 101, 102}
	count := copy(slice2, slice1)
	fmt.Println(count)
	count = copy(slice1, slice2)
	fmt.Println(count)
}

  

 

 


免責聲明!

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



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