Go 語言中的動態陣列:深入解析切片

閱讀時間約 9 分鐘


raw-image

👨‍💻簡介

在 Go 語言中,切片(Slice)是一種動態序列的資料結構,能夠方便地存儲和操作多個相同類型的元素。切片相比於陣列,更具有彈性,因為它的大小是可變的,可以根據需要動態增長或縮小。切片在處理集合型資料時非常實用,讓你能夠輕鬆地新增、刪除、修改和操作元素,同時避免了固定大小的限制。

切片的基本概念

切片是由一個指向陣列的指針、切片長度和切片容量組成的。切片的長度指的是切片中實際包含的元素個數,而切片的容量則是從切片開始的底層陣列中能夠訪問的元素個數。切片的容量可以大於或等於切片的長度。

宣告和初始化切片

在 Go 中,宣告和初始化切片可以使用以下的語法:

var slice1 []int                     // 創建一個整數切片,大小和容量都是 0
slice2 := []string{"A", "B", "C"} // 創建一個包含三個字串元素的切片
slice3 := make([]int, 5) // 創建一個整數切片,大小為 5,容量也為 5
slice4 := make([]int, 3, 5) // 創建一個整數切片,大小為 3,容量為 5

切片的基本操作

新增元素到切片

Go語言中有個內件函式append(),可以用來新增元素到切片中,這使得切片能夠根據需求動態增長。

numbers := []int{10, 20, 30}
numbers = append(numbers, 40, 50) // 新增兩個元素到切片

需要注意的是,如果切片的容量不足以容納新增的元素,append() 函式會創建一個新的切片,並將舊的元素和新的元素一同複製到新的切片中。

查詢和修改切片元素

切片的元素可以通過索引來存取,索引從 0 開始計數。

numbers := []int{10, 20, 30, 40, 50}
firstNumber := numbers[0] // 存取第一個元素,值為 10
secondNumber := numbers[1] // 存取第二個元素,值為 20
numbers[2] = 35 // 修改切片中的元素,將第三個元素改為 35

切割和遍歷切片

可以使用切片的切割操作來獲取部分切片,這可以通過指定切片的起始索引和結束索引來實現:

numbers := []int{10, 20, 30, 40, 50}
subSlice := numbers[1:4] // 從第二個元素到第四個元素的子切片,值為 [20 30 40]
  • [:]:使用 [:] 語法可以獲得完整的切片,即包含所有元素的切片。
  • [x:]:這種語法表示從索引 x 開始,提取所有直到切片結尾的元素。
  • [:x]:這種語法表示提取從開頭到索引 x-1 的元素,不包含索引 x 的元素。

切片的遍歷可以使用傳統的索引方式,或者使用 range 來簡化遍歷過程。

numbers := []int{10, 20, 30, 40, 50}

// 使用傳統的索引方式遍歷切片
for i := 0; i < len(numbers); i++ {
fmt.Println(numbers[i])
}
// 使用 range 遍歷切片
for index, value := range numbers {
fmt.Printf("索引:%d,值:%d\n", index, value)
}
for i := range numbers {
fmt.Println(numbers[i])
}

刪除切片元素

雖然切片沒有內建的刪除方法,不過可以使用切片的切割操作,將不需要的元素排除在外。

slice := []int{10, 20, 30, 40, 50}
indexToDelete := 2
slice = append(slice[:indexToDelete], slice[indexToDelete+1:]...) // 刪除索引 2 的元素

切片的容量

切片的容量就是指,你從切片開始的位置能夠往後訪問到的元素數量。當你在切片上進行新增元素的操作時,如果新加進來的元素數量超過了切片目前的容量,Go 語言會做一些事情:它會重新搞一個更大的陣列,然後把舊的元素都複製到這個新陣列中。這個過程會花一些時間,也就是所謂的性能開銷。

package main

import "fmt"
func main() {
numbers := []int{1, 2, 3}
fmt.Println("長度:", len(numbers)) // 輸出:長度:3
fmt.Println("容量:", cap(numbers)) // 輸出:容量:3
slice := numbers[1:2]
fmt.Println("切片:", slice) // 輸出:切片:[2]
fmt.Println("切片長度:", len(slice)) // 輸出:切片長度:1
fmt.Println("切片容量:", cap(slice)) // 輸出:切片容量:2
// 切片的容量是從切片的起始索引開始計算,一直到底層陣列的末尾索引。因此容量為2
// 新增元素超過切片容量時,會自動擴容並分配更大的底層陣列
slice = append(numbers, 4) // 新切片為 [1, 2, 3, 4]
fmt.Println("切片:", slice) // 輸出:切片:[1 2 3 4]
fmt.Println("切片長度:", len(slice)) // 輸出:切片長度:4
fmt.Println("切片容量:", cap(slice)) // 輸出:切片容量:6
}

切片的特性、限制與使用場景

切片的特性

  • 切片的大小是動態的,可以隨時進行增長或縮小。
  • 切片可以方便地從現有的陣列或切片中創建,不需要顯式地指定容量。
  • 切片的新增、刪除、修改操作都非常方便,讓你能夠輕鬆地操作集合型資料。
  • 切片的背後通常使用動態陣列來實現,因此在內存佈局上更具彈性,不受固定大小的限制。
  • 切片是引用類型,這意味著它們引用底層的陣列,而不是複製數據。當你將一個切片賦值給另一個切片,它們實際上共享同一份數據。因此,對其中一個切片所做的修改將影響到另一個切片。 以下是一個實際案例:
slice1 := []int{1, 2, 3}
slice2 := slice1
slice2[0] = 3
fmt.Println(slice1, slice2) // 輸出:[3 2 3] [3 2 3]

在這裡,修改 slice2 的值同樣影響了 slice1,因為它們引用同一份底層數據。這是切片和陣列之間的一個重要區別。

切片的限制

  • 記憶體配置: 切片的內部實現中使用了底層的陣列,因此切片所佔用的記憶體空間可能比實際所需大。當切片的元素數量增加時,Go 語言可能會重新配置更大的陣列,導致一些性能開銷。
  • 不適用於大型資料: 對於大型資料集合,切片可能不是最佳選擇。大型切片可能導致記憶體占用過多,影響程式的效能。
  • 不支援多維切片: 切片僅支援一維結構,如果需要處理多維資料,可能需要自行實現多維切片的概念。

使用場景

  • 動態資料集合: 切片的大小是可變的,使其非常適用於處理動態資料集合,無需事先知道集合的大小。
  • API 請求和回應: 在處理 API 請求和回應時,切片可用於儲存和解析不確定數量的請求參數或回應資料。
  • 資料過濾和轉換: 使用 range 遍歷切片,可以輕鬆地過濾或轉換切片中的元素,進行處理和計算。
  • 傳遞函式參數: 切片的引用類型特性使其適用於傳遞函式參數,避免不必要的資料複製。
  • 檔案讀寫: 切片可用於讀取大量數據,進行處理後再寫回檔案。
  • 實現堆疊和佇列: 使用切片可以實現簡單的堆疊(後進先出)和佇列(先進先出)結構。
  • 排序和搜尋: 切片在排序和搜尋資料時非常有用,可以利用 sort 套件進行排序,並使用二分搜尋等技術進行搜尋。

常見用法

  • 資料過濾和轉換
// 將切片中的所有元素乘以 2
numbers := []int{1, 2, 3, 4, 5}
for i := range numbers {
numbers[i] *= 2
}

// 過濾出大於 3 的元素
filteredNumbers := []int{}
for _, num := range numbers {
if num > 3 {
filteredNumbers = append(filteredNumbers, num)
}
}
  • 傳遞函式參數
func modifySlice(slice []int) {
slice[0] = 100
}

numbers := []int{1, 2, 3}
modifySlice(numbers)

小結

切片是 Go 語言中非常實用的資料結構,它解決了陣列大小固定的限制,讓你能夠輕鬆地處理動態大小的集合型資料。切片的操作包括取得、修改、新增、刪除等,讓你可以靈活地處理資料集合。

在遍歷切片時,range 很方便地提供了索引和值,讓你能夠輕鬆地訪問切片中的元素。切片的特性和優勢使得它在處理動態數據集合時成為 Go 程式設計中的一個重要工具。

📚Reference

17會員
83內容數
golang
留言0
查看全部
發表第一個留言支持創作者!
Alan的開發者天地 的其他內容
👨‍💻簡介 陣列就像是一個儲存相同類型資料的容器,你可以想像成裝滿了一樣東西的盒子,每個東西都叫做陣列元素。這種類型可以是基本的,像是整數或字串,也可以是你自己定義的型別。不過陣列有個限制,就是大小一旦確定就無法改變。在Go語言裡,陣列的長度也是型別的一部分。
👨‍💻簡介 本文簡單介紹了 Go 語言的流程控制概念,涵蓋了從條件語句到迴圈,再到 range 遍歷數據結構,以及 goto 與標籤 label 的應用。主要知識點為如何使用 if 語句進行條件判斷,以及在不同情況下運用 switch 語句。
👨‍💻簡介 本文快速介紹了 Go 語言中的各種運算符,從數學計算到邏輯判斷,包括自增自減、賦值、比較和位運算。透過實例和清晰的解釋,快速掌握如何在程式中運用這些運算符。
👨‍💻簡介 Go 語言有各種資料型別,分為基本型別和複合型別。基本型別包括: 整數、浮點數、布林值、字串 複合型別包括: 陣列、片段、結構、函式、對映、通道、介面 等。 整數型別 整數型別有許多種,像是 int8、int16、int32、int64。我們可以依據實際需求選擇。
👨‍💻簡介 在 Golang 中,你可以使用不同的方式來宣告變數和常數。宣告變數時,可以直接指定值,或者使用型別推導,更簡單地用 := 來宣告局部變數。另外,還可以一次宣告多個變數,相同型別的變數可以一起宣告,或者使用括號宣告不同型別的變數。常數則使用 const 關鍵字宣告,確保值不變
👨‍💻簡介 在這篇文章裡,會簡單介紹幾個關鍵的基本概念和語法結構,加快上手這門程式語言。
👨‍💻簡介 陣列就像是一個儲存相同類型資料的容器,你可以想像成裝滿了一樣東西的盒子,每個東西都叫做陣列元素。這種類型可以是基本的,像是整數或字串,也可以是你自己定義的型別。不過陣列有個限制,就是大小一旦確定就無法改變。在Go語言裡,陣列的長度也是型別的一部分。
👨‍💻簡介 本文簡單介紹了 Go 語言的流程控制概念,涵蓋了從條件語句到迴圈,再到 range 遍歷數據結構,以及 goto 與標籤 label 的應用。主要知識點為如何使用 if 語句進行條件判斷,以及在不同情況下運用 switch 語句。
👨‍💻簡介 本文快速介紹了 Go 語言中的各種運算符,從數學計算到邏輯判斷,包括自增自減、賦值、比較和位運算。透過實例和清晰的解釋,快速掌握如何在程式中運用這些運算符。
👨‍💻簡介 Go 語言有各種資料型別,分為基本型別和複合型別。基本型別包括: 整數、浮點數、布林值、字串 複合型別包括: 陣列、片段、結構、函式、對映、通道、介面 等。 整數型別 整數型別有許多種,像是 int8、int16、int32、int64。我們可以依據實際需求選擇。
👨‍💻簡介 在 Golang 中,你可以使用不同的方式來宣告變數和常數。宣告變數時,可以直接指定值,或者使用型別推導,更簡單地用 := 來宣告局部變數。另外,還可以一次宣告多個變數,相同型別的變數可以一起宣告,或者使用括號宣告不同型別的變數。常數則使用 const 關鍵字宣告,確保值不變
👨‍💻簡介 在這篇文章裡,會簡單介紹幾個關鍵的基本概念和語法結構,加快上手這門程式語言。
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
在進入主題之前建議先行閱讀「【程式語言 - Go】來認識Google開發的程式語言…」,初步認識一下Go語言是什麼? 容不容易學習? 才能夠更快的體會此篇章的目的。 當我們在進行軟體開發時,常常會需要有背後的資料庫系統來儲存我們的資料,而資料庫系統也會隨著時代的演進,進行大幅度的更新,那在這樣
Thumbnail
Golang(Go)是由Google開發的一種開源的、靜態型別的編程語言,目的在提供一個簡單、高效、安全以及易於擴展的程式語言,特別適用於並發和平行處理,Go語言設計上著重於開發者的生產力,並提供了現代化的語法和豐富的標準庫。 強調簡單易讀,讓我們回歸原始以最簡易的方式來撰寫程式,併發的特性讓日趨
Thumbnail
前言介紹 在 golang 1.16之後官方提供的工具包裡面有個 `embed` 可以使用,這使得把檔案嵌入 golang 的二進制編譯更為容易,以至於方便我們部署一些並非 .go 的副檔名檔案。 這裡要介紹的是如何把 vue 作為前端,編譯至我們的 golang 專案內,起一個網頁服務。 在開始
Thumbnail
由於Go語言本身沒有提供Enum的功能, 故我們可以使用package及type的技巧來達到類似的功能,假設今天要定義季節的enum型別, 包含了「春、夏、秋、冬」四種值的時候,可以怎麼做呢? 首先我們可以用package來框住season的範圍: 然而在season.go可以定義一個字串的類型 最
Thumbnail
(2022年2月21日,台北訊)2月對訓練家們是一個忙碌的月份,「Pokémon GO Tour:城都地區」將於2022年2月26日(星期六)9:00~21:00( 當日時間 )舉辦,緊接著隔天2月27日(星期天)更在高雄舉行全世界唯二的「Pokémon GO Tour:Live」實體活動!
Thumbnail
英國作者在一篇投稿中感嘆 小鎮(town)裡的五金雜貨店(hardware shops)都消失了, 他說: "Hardware shops in any small towns have gone the way of the dinosaurs."
Thumbnail
完整標題:go on 與「繼往走向」或「繼往開來」及「繼」、「續」、「繼續」、「接續」、「启開」、「正昂」、「發生」等的轉換密碼
Thumbnail
完整標題:go 與「之」、「至」、「至于」、「到」、「到于」、「前往」、「進往」、「步往」、「走」、「走于」、「走往」、「行」、「行于」、「行往」、「行走」、「去」、「過」、「過去」、「過于」、「步」、「步于」、「步往」、「步行」、「機遇」、「行旺」等的轉換密碼
Thumbnail
完整標題:go around 與「逛」、「觀覽」、「交往」、「相處」、「走訪」、「轉繞圓動」等的轉換密碼及「天狼星」之謎
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
在進入主題之前建議先行閱讀「【程式語言 - Go】來認識Google開發的程式語言…」,初步認識一下Go語言是什麼? 容不容易學習? 才能夠更快的體會此篇章的目的。 當我們在進行軟體開發時,常常會需要有背後的資料庫系統來儲存我們的資料,而資料庫系統也會隨著時代的演進,進行大幅度的更新,那在這樣
Thumbnail
Golang(Go)是由Google開發的一種開源的、靜態型別的編程語言,目的在提供一個簡單、高效、安全以及易於擴展的程式語言,特別適用於並發和平行處理,Go語言設計上著重於開發者的生產力,並提供了現代化的語法和豐富的標準庫。 強調簡單易讀,讓我們回歸原始以最簡易的方式來撰寫程式,併發的特性讓日趨
Thumbnail
前言介紹 在 golang 1.16之後官方提供的工具包裡面有個 `embed` 可以使用,這使得把檔案嵌入 golang 的二進制編譯更為容易,以至於方便我們部署一些並非 .go 的副檔名檔案。 這裡要介紹的是如何把 vue 作為前端,編譯至我們的 golang 專案內,起一個網頁服務。 在開始
Thumbnail
由於Go語言本身沒有提供Enum的功能, 故我們可以使用package及type的技巧來達到類似的功能,假設今天要定義季節的enum型別, 包含了「春、夏、秋、冬」四種值的時候,可以怎麼做呢? 首先我們可以用package來框住season的範圍: 然而在season.go可以定義一個字串的類型 最
Thumbnail
(2022年2月21日,台北訊)2月對訓練家們是一個忙碌的月份,「Pokémon GO Tour:城都地區」將於2022年2月26日(星期六)9:00~21:00( 當日時間 )舉辦,緊接著隔天2月27日(星期天)更在高雄舉行全世界唯二的「Pokémon GO Tour:Live」實體活動!
Thumbnail
英國作者在一篇投稿中感嘆 小鎮(town)裡的五金雜貨店(hardware shops)都消失了, 他說: "Hardware shops in any small towns have gone the way of the dinosaurs."
Thumbnail
完整標題:go on 與「繼往走向」或「繼往開來」及「繼」、「續」、「繼續」、「接續」、「启開」、「正昂」、「發生」等的轉換密碼
Thumbnail
完整標題:go 與「之」、「至」、「至于」、「到」、「到于」、「前往」、「進往」、「步往」、「走」、「走于」、「走往」、「行」、「行于」、「行往」、「行走」、「去」、「過」、「過去」、「過于」、「步」、「步于」、「步往」、「步行」、「機遇」、「行旺」等的轉換密碼
Thumbnail
完整標題:go around 與「逛」、「觀覽」、「交往」、「相處」、「走訪」、「轉繞圓動」等的轉換密碼及「天狼星」之謎