Go切片的具體使用
概述
在上一節(jié)的內(nèi)容中,我們介紹了Go的數(shù)組,包括:聲明數(shù)組、初始化數(shù)組、訪問(wèn)數(shù)組元素等。在本節(jié)中,我們將介紹Go的切片。在Go語(yǔ)言中,數(shù)組的長(zhǎng)度是固定的,不能改變,這在某些場(chǎng)景下使用不太方便。切片(slice)是一種動(dòng)態(tài)數(shù)組,它提供了更為靈活和便捷的方式來(lái)操作數(shù)組。切片是對(duì)數(shù)組的抽象,它包含了指向數(shù)組元素的指針、切片的長(zhǎng)度和容量。
聲明切片
切片的聲明使用[]操作符,語(yǔ)法如下:
var sliceName []Type
其中,sliceName表示切片的名稱,Type表示切片中元素的類型。與數(shù)組不同,聲明切片時(shí),不需要指定長(zhǎng)度。
在下面的示例代碼中,我們聲明了一個(gè)名為numbers的整數(shù)類型切片,并初始為空切片。
var numbers []int
初始化切片
可以使用數(shù)組來(lái)初始化切片,語(yǔ)法如下:
var sliceName []Type = []Type{value1, value2, ..., valueN}其中,Type表示切片中元素的類型,value1、value2、...、valueN是切片中元素的初始值。
在下面的示例代碼中,我們創(chuàng)建了一個(gè)包含3個(gè)整數(shù)的切片,其初始值為1、2、3。還創(chuàng)建了一個(gè)包含2個(gè)字符串的切片,其初始值為“Hello”、“CSDN”。
package main
import "fmt"
func main() {
var numbers []int = []int{1, 2, 3}
text := []string{"Hello", "CSDN"}
// 輸出:[1 2 3]
fmt.Println(numbers)
// 輸出:[Hello CSDN]
fmt.Println(text)
}我們還可以使用內(nèi)置函數(shù)make()來(lái)初始化切片,傳入類型、數(shù)量、容量(可忽略)即可,元素的初始值為類型的默認(rèn)值。
package main
import "fmt"
func main() {
var numbers []int = make([]int, 3)
text := make([]string, 2)
// 輸出:[0 0 0]
fmt.Println(numbers)
// 輸出:[ ]
fmt.Println(text)
}與數(shù)組相比,切片的長(zhǎng)度是不固定的,可以追加元素。在追加時(shí),可能使切片的容量增大。切片的長(zhǎng)度可以由 len()函數(shù)獲取,容量可以由cap()函數(shù)獲取。
package main
import "fmt"
func main() {
var numbers []int = make([]int, 3, 10)
// 輸出:3 10
fmt.Println(len(numbers), cap(numbers))
}如果切片聲明后,沒(méi)有初始化,則為空切片??涨衅J(rèn)為nil,其長(zhǎng)度和容量均為0。
package main
import "fmt"
func main() {
var numbers []int
// 輸出:0 0
fmt.Println(len(numbers), cap(numbers))
if numbers == nil {
// 輸出:[]
fmt.Println(numbers)
}
}切片的切割
在Go語(yǔ)言中,可以使用切片的切片操作來(lái)切割切片。切片的切片操作可以用來(lái)獲取切片的一部分,或者將一個(gè)切片分割成多個(gè)子切片。切片的切片操作使用兩個(gè)索引來(lái)指定切割的位置:第一個(gè)索引指定切割的起始位置,第二個(gè)索引指定切割的結(jié)束位置,但不包括該位置的元素。第一個(gè)索引不指定時(shí),默認(rèn)為0。第二個(gè)索引不指定時(shí),默認(rèn)為切片的長(zhǎng)度。
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5, 6}
// 輸出:[3 4 5 6]
fmt.Println(numbers[2:])
// 輸出:[1 2 3 4]
fmt.Println(numbers[:4])
// 輸出:[3 4]
fmt.Println(numbers[2:4])
// 輸出:[1 2 3 4 5 6]
fmt.Println(numbers[:])
}切片的添加
可以使用append()函數(shù)向切片添加一個(gè)或多個(gè)元素。append()函數(shù)會(huì)根據(jù)切片的容量和長(zhǎng)度,自動(dòng)調(diào)整底層數(shù)組的大小,并將新元素添加到切片的末尾。注意:append()函數(shù)會(huì)返回一個(gè)新的切片,包含添加元素后的結(jié)果;因此,需要將返回的結(jié)果重新賦值給原切片,以更新切片的內(nèi)容。
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3}
// 添加元素99和100到切片的末尾
numbers = append(numbers, 99, 100)
// 輸出:[1 2 3 99 100]
fmt.Println(numbers)
}當(dāng)向一個(gè)切片添加另一個(gè)切片的所有元素時(shí),使用append()函數(shù)需要對(duì)第二個(gè)切片進(jìn)行解包(切片后面添加符號(hào)...,用于展開(kāi)切片中的元素),可參考下面的示例代碼。
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3}
numbers2 := []int{99, 100}
// 添加另一個(gè)切片,需要解包
numbers = append(numbers, numbers2...)
// 輸出:[1 2 3 99 100]
fmt.Println(numbers)
}切片的刪除
切片的刪除分為幾種情況:從頭部刪除、從中間刪除、從尾部刪除。
刪除開(kāi)頭的元素時(shí),可以直接移動(dòng)數(shù)據(jù)指針。假如有一個(gè)切片slice,則slice[1:]會(huì)刪除開(kāi)頭1個(gè)元素,slice[N:]會(huì)刪除開(kāi)頭N個(gè)元素。
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5}
// 刪除開(kāi)頭2個(gè)元素
numbers = numbers[2:]
// 輸出:[3 4 5]
fmt.Println(numbers)
}也可以不移動(dòng)數(shù)據(jù)指針,但將后面的數(shù)據(jù)向開(kāi)頭移動(dòng),此時(shí)可用append()函數(shù)原地完成。
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5}
// 刪除開(kāi)頭2個(gè)元素
numbers = append(numbers[:0], numbers[2:]...)
// 輸出:[3 4 5]
fmt.Println(numbers)
}刪除中間的元素時(shí),需要對(duì)剩余元素進(jìn)行一次整體移動(dòng),此時(shí)仍可用append()函數(shù)原地完成。
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5, 6}
// 刪除中間的3、4兩個(gè)元素
numbers = append(numbers[:2], numbers[4:]...)
// 輸出:[1 2 5 6]
fmt.Println(numbers)
}刪除尾部的元素時(shí),直接切割即可。
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5, 6}
// 刪除尾部的兩個(gè)元素
numbers = numbers[:len(numbers) - 2]
// 輸出:[1 2 3 4]
fmt.Println(numbers)
}切片的復(fù)制
可以使用copy()函數(shù)來(lái)復(fù)制切片,它接受兩個(gè)參數(shù):第一個(gè)參數(shù)是目標(biāo)切片,第二個(gè)參數(shù)是源切片。copy()函數(shù)會(huì)將源切片中的元素復(fù)制到目標(biāo)切片中,并返回實(shí)際復(fù)制的元素個(gè)數(shù)。注意:如果源切片和目標(biāo)切片不一樣大,則會(huì)按照其中較小的那個(gè)切片的元素個(gè)數(shù)進(jìn)行復(fù)制。另外,切片的復(fù)制不是在末尾添加元素,而是從開(kāi)頭位置覆蓋之前已經(jīng)存在的元素。
package main
import "fmt"
func main() {
slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{66, 88, 99}
// slice2的容量小,故只會(huì)復(fù)制slice1的前3個(gè)元素到slice2中
copy(slice2, slice1)
// 輸出:[1 2 3]
fmt.Println(slice2)
slice2 = []int{66, 88, 99}
copy(slice1, slice2)
// 輸出:[66 88 99 4 5]
fmt.Println(slice1)
}切片的遍歷
有兩種方法來(lái)實(shí)現(xiàn)切片的遍歷:一是使用for循環(huán),二是使用range關(guān)鍵字。
在下面的示例代碼中,我們使用了一個(gè)for循環(huán),從切片的索引0開(kāi)始遍歷到切片的長(zhǎng)度減1。通過(guò)索引,我們可以訪問(wèn)切片中的每個(gè)元素,并打印出來(lái)。
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5}
for i := 0; i < len(numbers); i++ {
fmt.Println(numbers[i])
}
}在下面的示例代碼中,我們使用了range關(guān)鍵字來(lái)遍歷切片。每次迭代時(shí),range會(huì)返回當(dāng)前元素的索引和值。我們可以使用它們來(lái)訪問(wèn)切片中的元素,這種方法更加簡(jiǎn)潔和易讀。
package main
import "fmt"
func main() {
numbers := []int{1, 2, 3, 4, 5}
for index, value := range numbers {
fmt.Println(index, value)
}
}多維切片
多維切片是由一系列切片組成的,每個(gè)切片可以具有不同的長(zhǎng)度和容量。要?jiǎng)?chuàng)建一個(gè)多維切片,首先需要?jiǎng)?chuàng)建一個(gè)初始切片。然后使用該切片來(lái)創(chuàng)建額外的切片,每個(gè)新切片都會(huì)將原始切片的元素拆分為更小的切片。
聲明一個(gè)多維切片的語(yǔ)法格式如下:
var sliceName [][]...[]Type
其中,sliceName表示切片的名稱,Type表示切片的類型,每個(gè)[]代表著一個(gè)維度,切片有幾個(gè)維度就需要幾個(gè)[]。
在下面的示例代碼中,我們首先創(chuàng)建了一個(gè)初始切片slice,長(zhǎng)度為3。然后,我們使用range循環(huán)為每個(gè)內(nèi)部切片創(chuàng)建了長(zhǎng)度為2的子切片。接下來(lái),我們給多維切片中的元素進(jìn)行了賦值。最后,我們使用嵌套的range循環(huán)打印了多維切片的內(nèi)容。
package main
import "fmt"
func main() {
// 創(chuàng)建一個(gè)初始切片,長(zhǎng)度為3
slice := make([][]int, 3)
for i := range slice {
// 每個(gè)內(nèi)部切片長(zhǎng)度為2
slice[i] = make([]int, 2)
}
// 給多維切片中的元素賦值
slice[0][0] = 50
slice[0][1] = 60
slice[1][0] = 70
slice[1][1] = 80
slice[2][0] = 90
slice[2][1] = 100
// 打印多維切片的內(nèi)容
for i := range slice {
for j := range slice[i] {
fmt.Println(slice[i][j])
}
}
}到此這篇關(guān)于Go切片的具體使用的文章就介紹到這了,更多相關(guān)Go切片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- go中實(shí)現(xiàn)字符切片和字符串互轉(zhuǎn)
- Golang切片連接成字符串的實(shí)現(xiàn)示例
- Go語(yǔ)言之重要數(shù)組類型切片(slice)make,append函數(shù)解讀
- GO語(yǔ)言中創(chuàng)建切片的三種實(shí)現(xiàn)方式
- golang字符串切片去重的幾種算法
- 詳解golang的切片擴(kuò)容機(jī)制
- 一文詳解Go語(yǔ)言中切片的底層原理
- Go?語(yǔ)言中切片的三種特殊狀態(tài)
- 淺談go中切片比數(shù)組好用在哪
- 一文總結(jié)Go語(yǔ)言切片核心知識(shí)點(diǎn)和坑
- 深入剖析Go語(yǔ)言中數(shù)組和切片的區(qū)別
- Go語(yǔ)言實(shí)戰(zhàn)之切片內(nèi)存優(yōu)化
相關(guān)文章
使用golang引入外部包的三種方式:go get, go module, ve
這篇文章主要介紹了使用golang引入外部包的三種方式:go get, go module, vendor目錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
go-micro集成RabbitMQ實(shí)戰(zhàn)和原理詳解
本文主要介紹go-micro使用RabbitMQ收發(fā)數(shù)據(jù)的方法和原理,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
淺談go語(yǔ)言閉包的立即執(zhí)行和不立即執(zhí)行
Go語(yǔ)言中的閉包是一種可以訪問(wèn)其定義時(shí)所在作用域變量的特殊函數(shù),閉包可以分為立即執(zhí)行和不立即執(zhí)行兩種,本文就來(lái)介紹一下go語(yǔ)言閉包的立即執(zhí)行和不立即執(zhí)行,感興趣的可以了解一下2025-03-03
golang?cache帶索引超時(shí)緩存庫(kù)實(shí)戰(zhàn)示例
這篇文章主要為大家介紹了golang?cache帶索引超時(shí)緩存庫(kù)實(shí)戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Go語(yǔ)言常見(jiàn)錯(cuò)誤之誤用init函數(shù)實(shí)例解析
Go語(yǔ)言中的init函數(shù)為開(kāi)發(fā)者提供了一種在程序正式運(yùn)行前初始化包級(jí)變量的機(jī)制,然而,由于init函數(shù)的特殊性,不當(dāng)?shù)厥褂盟赡芤鹨幌盗袉?wèn)題,本文將深入探討如何有效地使用init函數(shù),列舉常見(jiàn)誤用并提供相應(yīng)的避免策略2024-01-01

