golang學習筆記 ---陣列與切片
陣列:
- golang陣列包含的每個資料稱為陣列元素(element),陣列包含的元素個數被稱為陣列長度(length)。
- golang陣列的長度在定義後不可更改,並且在宣告時可以是一個常量或常量表達式(在編譯期即可計算結果的表示式)。golang陣列長度是一個內建常量,可以用len()函式來獲取。
- golang陣列是一個值型別,在賦值和作為引數傳遞時都將產生一次複製動作,因此在函式體中無法修改傳入的陣列的內容。
陣列宣告和初始化
▶ 陣列宣告
▪ 語法如下
var array [n]Type // 陣列宣告和初始化 var array [n]Type = [n]Type{v1, v2, ..., vn} var array = [n]Type{v1, v2, ..., vn} array := [n]Type{v1, v2, ..., vn}
▪ 示例如下
[32]byte // 長度為32的陣列,每個元素為一個位元組 [2*N] struct { x, y int32 } // 複雜型別陣列 [1000]*float64 // 指標陣列 [3][5]int // 二維陣列 [2][2][2]float64 // 等同於[2]([2]([2]float64))
• 陣列常用操作
▶ 遍歷元素
⊙ 按下標遍歷
√ 使用len()獲取元素個數,然後按下標進行元素遍歷操作。
▪ 語法如下
for i := 0; i < len(array); i++ { ... }
▪ 示例如下
package main
import "fmt"
func main() {
array := [5]int{1, 2, 3, 4, 5}
for i := 0; i < len(array); i++ {
fmt.Println("array[", i, "] =", array[i])
}
}
⊙ rang遍歷
√ 可以使用range關鍵字來快速遍歷所有元素。
▪ 語法如下
for i, v := range array { ... }
▪ 示例如下
package main
import "fmt"
func main() {
array := [5]int{1, 2, 3, 4, 5}
for i, v := range array {
fmt.Println("array[", i, "] =", v)
}
}
陣列切片
√ golang陣列切片解決的問題:golang陣列長度在定義之後無法再次修改,並且陣列是值型別,每次傳遞都將產生一份副本。
√ golang陣列切片擁有獨立的資料結構,可抽象為3個變數:一個指向原陣列的指標,陣列切片中元素個數,陣列切片分配的儲存空間。
• 建立陣列切片
▶ 基於陣列
▪ 語法如下
var arraySlice []Type = array[first:last]
√ 陣列切片的元素範圍為[first, last)。
√ first和last的值可以省略,預設情況下,first=0,last=len(array)
√ first和last的值必須滿足條件:非負,0 ≤ first ≤ last ≤ len(array),否則編譯器將給出錯誤:
▪ 示例如下
package main
import "fmt"
func main() {
var array [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
var arraySlice1 []int = array[:] // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
var arraySlice2 []int = array[:5] // 1, 2, 3, 4, 5
var arraySlice3 []int = array[5:] // 6, 7, 8, 9, 10
var arraySlice4 []int = array[3:8] // 4, 5, 6, 7, 8
fmt.Println("\nElements of arraySlice1: ")
for _, v := range arraySlice1 {
fmt.Print(v, " ")
}
fmt.Println("\nElements of arraySlice2: ")
for _, v := range arraySlice2 {
fmt.Print(v, " ")
}
fmt.Println("\nElements of arraySlice3: ")
for _, v := range arraySlice3 {
fmt.Print(v, " ")
}
fmt.Println("\nElements of arraySlice4: ")
for _, v := range arraySlice4 {
fmt.Print(v, " ")
}
fmt.Println()
}
▶ 直接建立
√ golang提供的內建函式make()可以用於靈活地建立陣列切片。
▪ 語法如下
// 建立一個初始元素個數為m的陣列切片 arraySlice := make([]Type, m) // 建立一個初始元素個數為m的陣列切片,並預留n個元素的儲存空間 arraySlice := make([]Type, m, n) // 直接建立並初始化包含m個元素的陣列切片 arraySlice := []Type{v1, v2, ..., vn}
▪ 示例如下
package mainimport "fmt"
func main() {
arraySlice1 := make([]int, 5) // 0 0 0 0 0
arraySlice2 := make([]int, 5, 10) // 0 0 0 0 0
arraySlice3 := []int{1, 2, 3, 4, 5} // 1 2 3 4 5
fmt.Println("\nElements of arraySlice1: ")
for _, v := range arraySlice1 {
fmt.Print(v, " ")
}
fmt.Println("\nElements of arraySlice2: ")
for _, v := range arraySlice2 {
fmt.Print(v, " ")
}
fmt.Println("\nElements of arraySlice3: ")
for _, v := range arraySlice3 {
fmt.Print(v, " ")
}
}
▶ 基於陣列切片
√ 陣列切片(newSlice)也可以基於另一個數組切片(oldSlice)建立。
√ newSlice元素範圍可以超過oldSlice所包含的元素個數,只要選擇範圍不超過oldSlice的儲存能力,即cap(oldSlice)的值,那麼這個建立是合法的,newSlice中超出oldSlice元素的部分都會填上0。
√ newSlice的儲存能力等同於oldSlice的儲存能力,即cap(newSlice) = cap(oldSlice)。
▪ 語法如下
newSlice := oldSlice[first:last] // 0 ≤ first ≤ last ≤ cap(oldSlice)
▪ 示例如下
package main
import "fmt"
func main() {
oldSlice := make([]int, 5, 10)
newSlice := oldSlice[:8]
fmt.Println("Length of oldSlice: ", len(oldSlice)) // 5
fmt.Println("Capacity of oldSlice: ", cap(oldSlice)) // 10
fmt.Println("Length of newSlice: ", len(newSlice)) // 8
fmt.Println("Capacity of newSlice: ", cap(newSlice)) // 10
}
• 陣列切片的元素個數和儲存能力
√ 與陣列相比,陣列切片多了一個儲存能力(capacity)的概念,即當前容納的元素個數和分配的空間可以是兩個不同的值。
√ 儲存能力,可以理解為最大容納元素個數,最大容納元素個數減去當前容納元素個數剩下的空間是隱藏的,不能直接使用。如果要往隱藏空間中新增元素,可以使用append()函式。
√ 取得當前容納元素個數可以使用len()函式,取得最大容納元素個數可以使用cap()函式。
package main
import "fmt"
func main() {
arraySlice := make([]int, 5, 10)
fmt.Println("len(arraySlice):", len(arraySlice)) // len(arraySlice): 5
fmt.Println("cap(arraySlice):", cap(arraySlice)) // cap(arraySlice): 10
}
• 陣列切片常用操作
▶ 遍歷元素
⊙ 按下標遍歷
√ 與遍歷陣列一樣,使用len()獲取元素個數,然後按下標進行元素遍歷操作。
▪ 語法如下
for i := 0; i < len(arraySlice); i++ { ... }
▪ 示例如下
package main
import "fmt"
func main() {
arraySlice := []int{1, 2, 3, 4, 5}
for i := 0; i < len(arraySlice); i++ {
fmt.Println("arraySlice[", i, "] =", arraySlice[i])
}
}
⊙ rang遍歷
√ 與遍歷陣列一樣,可以使用range關鍵字來快速遍歷所有元素。
▪ 語法如下
for i, v := range arraySlice { ... }
▪ 示例如下
package main
import "fmt"
func main() {
arraySlice := []int{1, 2, 3, 4, 5}
for i, v := range arraySlice {
fmt.Println("arraySlice[", i, "] =", v)
}
}
▶ 增加元素
√ 為陣列切片增加元素的方法是使用append()函式。
⊙ 追加元素
√ 追加元素時,會自動處理儲存空間不足的問題,如果追加的內容超過當前最大容納元素空間,那麼陣列切片會自動分配一塊足夠大的記憶體。自動分配記憶體策略為:當前儲存能力 * 2,即cap(arraySlice) * 2。
▪ 語法如下
arraySlice = append(arraySlice, v1, v2, ..., vn)
▪ 示例如下
package main
import "fmt"
func main() {
arraySlice := make([]int, 0, 10)
arraySlice = append(arraySlice, 1, 2, 3, 4, 5)
fmt.Println("len(arraySlice) =", len(arraySlice)) // 5
fmt.Println("cap(arraySlice) =", cap(arraySlice)) // 10
for _, v := range arraySlice {
fmt.Print(v, " ")
}
fmt.Println()
arraySlice = append(arraySlice, 6, 7, 8, 9, 10, 11, 12, 13)
fmt.Println("len(arraySlice) =", len(arraySlice)) // 13
fmt.Println("cap(arraySlice) =", cap(arraySlice)) // 20
for _, v := range arraySlice {
fmt.Print(v, " ")
}
}
⊙ 追加陣列切片
√ 為陣列切片arraySlice1追加陣列切片arraySlice2時,注意在arraySlice2後面追加三個點,這三個點的意思是把arraySlice2所有元素打散後傳遞給append()函式,這是由於append()函式從第二個引數起的所有引數都必須是待附加的單個元素。
▪ 語法如下
arraySlice = append(arraySlice, appendSlice...)
▪ 示例如下
package main
import "fmt"
func main() {
arraySlice := []int{1, 2, 3}
appendSlice := []int{4, 5}
arraySlice = append(arraySlice, appendSlice...)
fmt.Println("len(arraySlice) =", len(arraySlice)) // 5
fmt.Println("cap(arraySlice) =", cap(arraySlice)) // 6
for _, v := range arraySlice {
fmt.Print(v, " ")
}
}
▶ 刪除元素
√ 陣列切片可以動態新增元素,但沒有刪除元素的函式。代替方法是:可以使用陣列切片重新組合的方式來刪除一個或多個項。不過從陣列切片這種資料結構來看,本身並不適合做刪除操作,所以儘量減少使用。
▪ 示例如下
package main
import "fmt"
func main() {
s := []int{1, 2, 3, 4, 5, 6}
i := 2
s = append(s[:i], s[i+1:]...)
fmt.Println(s) // [1 2 4 5 6]
}
▶ 切片之間元素複製
√ golang使用內建函式copy()將陣列切片arraySlice2的內容複製到陣列切片arraySlice1中。
√ 如果兩個陣列切片元素個數不同,那麼就會按其中元素個數較少的陣列切片元素個數進行復制操作。
▪ 示例如下
package main
import "fmt"
func main() {
arraySlice1 := []int{1, 2, 3, 4, 5}
arraySlice2 := []int{5, 4, 3}
copy(arraySlice2, arraySlice1) // 只會複製arraySlice1的前3個元素到arraySlice2中
fmt.Println(arraySlice2) // [1 2 3]
arraySlice3 := []int{1, 2, 3, 4, 5}
arraySlice4 := []int{5, 4, 3}
copy(arraySlice3, arraySlice4) // 只會複製arraySlice4的3個元素到arraySlice3的前3個位置
fmt.Println(arraySlice3) // [5 4 3 4 5]
}
相關推薦
golang學習筆記 ---陣列與切片
陣列: golang陣列包含的每個資料稱為陣列元素(element),陣列包含的元素個數被稱為陣列長度(length)。 golang陣列的長度在定義後不可更改,並且在宣告時可以是一個常量或常量表達式(在編譯期即可計算結果的表示式)。golang陣列長度是一個內建常量,可以用len()函式來獲取。 gol
go語言學習筆記--陣列與切片
一、陣列 基本概念 1、一組相同型別已編號且長度固定的資料項序列 宣告格式:var identifier [len]type 2、Go語言中陣列是一種值型別,不是c中指向首元素地址,函式中使用 陣列作為引數,是值傳遞,會產生一次陣列拷貝。不會修改原資料 3、將陣列傳
golang學習筆記 ---數組與切片
info lds 位置 內存 print city func 超過 src 數組: golang數組包含的每個數據稱為數組元素(element),數組包含的元素個數被稱為數組長度(length)。 golang數組的長度在定義後不可更改,並且在聲明時可以是一個常量或常量表
深入學習golang(1)—陣列與切片
資料(array)與切片(slice) 陣列宣告: ArrayType = "[" ArrayLength "]" ElementType . 例如: var a [32] int var b [3][5] int 在Go和C中,陣列的工作方式有幾個重要的差別。在Go中, (1)陣列是值型別。將一個數組
[Golang學習筆記] 07 陣列和切片
01-06回顧: Go語言開發環境配置, 常用原始碼檔案寫法, 程式實體(尤其是變數)及其相關各種概念和程式設計技巧: 型別推斷,變數重宣告,可重名變數,型別推斷,型別轉換,別名型別和潛在型別 陣列: 陣列型別的值的長度是固定的,在宣告陣列的時候,長度必須給定,並且在之後不
資料結構與演算法之美專欄學習筆記-陣列
什麼是陣列 陣列(Array)是一種線性表資料結構。它用一組連續的記憶體空間,來儲存一組具有相同型別的資料。 線性表 線性表就是資料排成像一條線一樣的結構。 常見的線性表結構:陣列,連結串列、佇列、棧等。 非線性表有:二叉樹、圖、堆等。 連續的記憶體空間和相同型別的資料 優點:兩限制使得
Go學習筆記陣列切片和容器(五)
func main() { //定義陣列 數量在型別的前面 var arr [5] int // 不定義值為0 arr1 := [3]int{1} // := 必須賦值 最少賦值1位 arr2 := [...]int{4,5,6,7,8} //...可不規定長度 //二維陣列 var
golang 學習筆記 ---記憶體分配與管理
Go語言——記憶體管理 參考: 圖解 TCMalloc Golang 記憶體管理 Go 記憶體管理 問題 記憶體碎片:避免記憶體碎片,提高記憶體利用率。 多執行緒:穩定性,效率問題。 記憶體分配 記憶
golang學習筆記之引用型別與值型別
在golang中只有三種引用型別它們分別是切片slice、字典map、管道channel。其它的全部是值型別,引用型別可以簡單的理解為指標型別,它們都是通過make完成初始化 看下面兩個例子: a :=[5]int{2,3,4,5,6}
《Go語言核心36講》筆記8:陣列與切片
回顧 前面幾節都是關於Go語言的基礎知識,包括開發環境配置、常用原始碼檔案語法,以及程式實體、變數及其相關概念和技巧(如型別推斷、變數重宣告、可重名變數、型別斷言、型別轉換、別名型別和潛在型別等),這些都是學習Go語言的基礎,務必要清楚每一個細節,也可以自己寫程式碼實踐一下
手把手golang教程【二】——陣列與切片
本文始發於個人公眾號:**TechFlow**,原創不易,求個關注 今天是golang專題的第五篇,這一篇我們將會了解golang中的陣列和切片的使用。 陣列與切片 golang當中陣列和C++中的定義類似,除了變數型別寫在後面。 比如我們要宣告一個長度為10的int型的陣列,會寫成這樣: var a
linux學習筆記--程序與進程管理
ref monitor vim 子進程 free task 排序 image ctrl 、工作管理 1、前臺程序放後臺程序 命令後 加 & 2、任務執行時將前臺任務任務放到後臺中並【暫停】 ctr + z 3、jobs 觀察後臺工作狀態 及多少任務
golang學習筆記(1):安裝&helloworld
golang安裝:golang編譯器安裝過程比較簡單,也比較快,不同平臺下(win/linux/macos)都比較相似;https://dl.gocn.io/golang/1.9.2/go1.9.2.src.tar.gz 下載對應的系統版本的編譯器go的版本號由"." 分為3部分如當前的
學習筆記--概率與期望
推廣 可能 試驗 同時 導致 取出 集合 .com strong 相關概念 基本事件ω(也稱樣本點): 一次試驗可能出現的每一個直接的 結果。也就是隨機試驗不能夠再分解的結果。 如:E1有兩個基本事件:E1 ={出現正面}, E2={出現反面} E2有六個基本事件
shell腳本編程學習筆記-分支與循環結構
linux shell 1.1 if語句 (1)if條件語句語法:單分支結構 if [ 條件 ] then 指令 fi 或 if [ 條件 ];then 指令 fi if 單分支條件中文編程形象語法 如果 [ 你有房 ] 那麽 我就嫁給你 果如 前面的文件條件表達式[ -f “$file1” ]&
ES6學習筆記----陣列的擴充套件
1、Array.from 應用兩類:類似於陣列的物件和可遍歷的的物件(包含Map和Set),只有轉換成真正的陣列,才可使用陣列的方法。 類比:...擴充套件運算子也可以使某些物件變成陣列 2、Array.of 主要彌補陣列建構函式Array(
Golang學習筆記(八)switch分支語句
Golang的switch可以不用在每個case裡寫一個break,Golang會自動加入。 default關鍵字可以帶,也可以不帶,不是必須要有的。 首先是一個最基礎的示例,在switch後面帶一個變數。 func ScoreGrade1() { gradel := "B" s
Golang學習筆記(七)if判斷語句
golang的判斷語句,不再需要用()來括起條件,但{必須跟if在一行。和java一樣,也有else關鍵字。 基礎例子,判斷奇偶數,給出一個值30,讓程式來判斷。 func EvenOdd(){ num := 30 if num % 2 == 0 { fmt.Println(nu
Golang學習筆記(六)運算子
實在是沒有什麼好寫的,寫幾個函式來體現幾個運算子。 新建一個go file,新增三個變數 var a = 21.0 var b = 5.0 var c float64 建一個函式來體現算術運算子 func Arithmetic() { c = a + b fmt.Printf
Golang學習筆記(五)常量及iota
Golang語言申明常量,需要用到一個關鍵字const。 const STR1 string = "hello" 大家習慣性的將常量設定為全大寫,但在Golang裡面是沒有private、public等許可權設定的,這些許可權僅靠方法、函式、變數等的首字母大小寫來設定,所以如果全大寫,將