Go語言中切片slice的宣告與使用
一、切片slice的定義
Go語言中的切片,是一種動態陣列,它是對陣列的擴充套件。
- 與陣列相⽐,切⽚的⻓度是不固定的,可以追加元素,在追加時可能使切⽚的容量增⼤。
- 切⽚本身沒有任何資料,它們只是對現有陣列的引⽤。
- 切⽚與陣列相⽐,不需要設定⻓度,在[]中不⽤設定值,相對來說⽐較⾃由。
- 從概念上⾯來說slice像⼀個結構體,這個結構體包含了三個元素:
1)指標,指向陣列中slice指定的開始位置;
2)⻓度,即slice的⻓度;
3)最⼤⻓度,也就是slice開始位置到陣列的最後位置的⻓度。
二、切片的語法
2.1 宣告切片
2.1.1 宣告⼀個未指定⻓度的陣列來定義切⽚
- var identifier []type
- 切⽚不需要說明⻓度;
- 該宣告⽅式,且未初始化的切⽚為空切⽚。該切⽚預設為 nil,⻓度為 0。
2.1.2 使⽤make()函式來建立切⽚:
- var slice1 []type = make([]type, len)
- 可以簡寫為: slice1 := make([]type, len)
- 可以指定容量,其中capacity為可選引數: make([]T, length, capacity)
//mySlice.go
package main
import (
"fmt"
)
func main() {
//fmt.Println("Hello World!")
//1)切片
var numbers = make([]int, 3, 5)
fmt.Printf("%T\n", numbers)
fmt.Printf("len=%d cap=%d slice=%v\n", len(numbers), cap(numbers), numbers)
}
效果如下:
2.2 初始化
2.2.1 直接初始化切片
s :=[] int {1,2,3 }
2.2.2 通過陣列擷取來初始化切⽚
陣列: arr := [5]int {1,2,3,4,5}
- 1)s := arr[:]
切⽚中包含陣列所有元素 - 2)s := arr[startIndex:endIndex]
將arr中從下標startIndex到endIndex-1 下的元素建立為⼀個新的切⽚(前閉後開),⻓度為endIndex-startIndex - 3)s := arr[startIndex:]
預設endIndex時將表示⼀直到arr的最後⼀個元素; - 4)s := arr[:endIndex]
預設startIndex時將表示從arr的第⼀個元素開始。
2.2.3 通過切片擷取來初始化切片
可以通過設定下限及上限來設定擷取切⽚ [lower-bound:upper-bound]
//mySlice2.go
package main
import (
"fmt"
)
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
func main() {
//fmt.Println("Hello World!")
//1)切片
// var numbers = make([]int, 3, 5)
// fmt.Printf("%T\n", numbers)
// fmt.Printf("len=%d cap=%d slice=%v\n", len(numbers), cap(numbers), numbers)
//2)擷取切片
numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
printSlice(numbers)
//列印原始切片
fmt.Println("numbers== ", numbers)
//列印子切片,從索引1到索引4,左閉右開,[1,4)
fmt.Println("numbers[1:4]== ", numbers[1:4])
//預設下限為0,[0,3)
fmt.Println("numbers[:3]== ", numbers[:3])
//預設上限為len(s),[4,len(s))
fmt.Println("numbers[4:]== ", numbers[4:])
//列印子切片,[0,2)
number2 := numbers[:2]
printSlice(number2)
//列印子切片,[2,5)
number3 := numbers[2:5]
printSlice(number3)
}
效果如下:
三、切片裡的len()和cap()函式
- 切⽚的⻓度是切⽚中元素的數量。
- 切⽚的容量是從建立切⽚的索引開始的底層陣列中元素的數量。
- 切⽚是可索引的,並且可以由 len() ⽅法獲取⻓度, 切⽚提供了計算容量的⽅法 cap(), 可以測量切⽚最⻓可以達到多少。 [陣列計算cap()結果與len()相同]。
- 切⽚實際的是獲取陣列的某⼀部分, len切⽚<=cap切⽚<=len陣列。
- cap()的結果決定了切⽚擷取的注意細節。
//mySlice02.go
// mySliceCap project main.go
package main
import (
"fmt"
)
func main() {
sliceCap()
}
func sliceCap() {
arry := [...]string{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"}
fmt.Println("cap(arry)= ", cap(arry), arry)
//擷取陣列,形成切片
sli01 := arry[2:8]
fmt.Printf("%T\n", sli01)
fmt.Println("cap(sli01)= ", cap(sli01), sli01)
sli02 := arry[4:7]
fmt.Println("cap(sli02)= ", cap(sli02), sli02)
//擷取切片,形成切片
sli03 := sli01[3:9]
fmt.Println("擷取sli01[3:9]後形成sli03: ", sli03)
sli04 := sli02[4:7]
fmt.Println("擷取sli02[4:7]後形成sli04: ", sli04)
//切片是引用型別
sli04[0] = "x"
fmt.Print(arry, sli01, sli02, sli03, sli04)
}
執行結果如下:
四、切片是引用型別
- slice沒有⾃⼰的任何資料,它只是底層陣列的⼀個引⽤,對slice所做的任何修改都將反映在底層陣列中。
- 陣列是值型別,⽽切⽚是引用型別。
修改陣列的案例,如下:
//mySlice04.go
// mySliceCmp project main.go
package main
import (
"fmt"
)
func main() {
a := [4]float64{67.7, 89.8, 21, 78}
b := []int{2, 3, 5}
fmt.Printf("變數a -- 地址: %p, 型別: %T, 數值: %v, 長度: %d\n", &a, a, a, len(a))
fmt.Printf("變數b -- 地址: %p, 型別: %T, 數值: %v, 長度: %d\n", &b, b, b, len(b))
c := a
d := b
fmt.Printf("變數c -- 地址: %p, 型別: %T, 數值: %v, 長度: %d\n", &c, c, c, len(c))
fmt.Printf("變數d -- 地址: %p, 型別: %T, 數值: %v, 長度: %d\n", &d, d, d, len(d))
a[1] = 200
fmt.Println("a= ", a, " c= ", c)
d[0] = 100
fmt.Println("b= ", b, " d= ", d)
}
執行結果如下:
- 修改切⽚數值
當多個⽚共享相同的底層陣列時,每個元素所做的更改將在陣列中反映出來。
修改切片裡的值,案例如下:
//mySlice04.go
// mySliceChg project main.go
package main
import (
"fmt"
)
func main() {
//定義陣列
arry := [3]int{1, 2, 3}
//根據陣列擷取切片
nums1 := arry[:]
nums2 := arry[:]
fmt.Println("arry= ", arry)
nums1[0] = 100
fmt.Println("arry= ", arry)
nums2[1] = 200
fmt.Println("arry= ", arry)
fmt.Printf("變數arry --地址: %p\n", &arry)
fmt.Printf("變數nums1 --地址: %p\n", &nums1)
fmt.Printf("變數nums2 --地址: %p\n", &nums2)
}
執行結果如下:
相關文章
- Go 語言中的 切片 --sliceGo
- 聊聊Go語言中的陣列與切片Go陣列
- Go 語言中的兩種 slice 表示式Go
- Go中的切片SliceGo
- Go語言之切片(slice)快速入門篇Go
- go語言 變數的宣告與使用Go變數
- 深度解析 Go 語言中「切片」的三種特殊狀態Go
- Go 切片 slice - Go 學習記錄Go
- Go 語言中的 collect 使用Go
- Go slice切片的“陷阱”和本質Go
- c語言中陣列的宣告與初始化C語言陣列
- Go 語言中使用 ETCDGo
- Slice切片
- go語言之陣列與切片Go陣列
- Go 語言中的方法Go
- GO語言————7.5 切片的複製與追加Go
- go slice使用Go
- GO slice 切片-在記憶體中如何分配Go記憶體
- Go語言中JSON標籤的用法與技巧GoJSON
- go 語言切片Go
- 在Go語言中,怎樣使用Json的方法?GoJSON
- Go 語言中的外掛Go
- go語言變數的宣告與賦值Go變數賦值
- Slice(切片)- 《Go 專家程式設計》筆記提要Go程式設計筆記
- Go 語言中 defer 使用時有哪些陷阱?Go
- Go語言————7.2 切片Go
- 【Go語言基礎】sliceGo
- 深度解密Go語言之Slice解密Go
- Go語言中的併發模式Go模式
- GO 語言中的物件導向Go物件
- Go語言slice的本質-SliceHeaderGoHeader
- Golang 陣列和切片 Slice 和 Map 使用Golang陣列
- go語言使用切片實現線性表Go
- 在 Go 語言中,我為什麼使用介面Go
- day05 切片slice
- 【譯】Go語言宣告語法Go
- 認識 Go 語言中的陣列Go陣列
- Go語言中的變數作用域Go變數