package main
func main()
執行成功~
補充:golang slice 詳解
func main()
var slice = array[1:7] //array[startindex:endindex] 不包含endindex
//2.直接建立陣列切片
slice2 := make(int, 5, 10)
//3.直接建立並初始化陣列切片
slice3 := int
//4.基於陣列切片建立陣列切片
slice5 := slice3[:4]
//5.遍歷陣列切片
for i, v := range slice3
和cap()
var len = www.cppcns.comlen(slice2) //陣列切片的長度
var cap = cap(slice) //陣列切片的容量
fmt.println("len(slice2) =", len)
fmt.println("cap(slice) =", cap)
會生成新的陣列切片
slice4 := append(slice2, 6, 7, 8)
slice4 = append(slice4, slice3...)
fmt.println(slice4)
如果進行操作的兩個陣列切片元素個數不一致,將會按照個數較小的陣列切片進行複製
copy(slice2, slice3) //將slice3的前五個元素複製給slice2
fmt.println(slice2, slice3)
}陣列切片slice的資料結構如下,乙個指向真實array位址的指標ptr,slice的長度len和容量cap
程式設計客棧
// slice 資料結構
type slice struct
當傳參時,函式接收到的引數是陣列切片的乙個複製,雖然兩個是不同的變數,但是它們都有乙個指向同乙個位址空間的array指標,當修改乙個陣列切片時,另外乙個也會改變,所以陣列切片看起來是引用傳遞,其實是值傳遞。
執行以下**思考乙個問題:s1和s2是指向同乙個底層陣列嗎?
func main()
s1 := array[:5]
s2 := append(s1, 10)
fmt.println("s1 =", s1)
fmt.println("s2 =", s2)
s2[0] = 0
fmt.println("s1 =", s1)
fmt.println("s2 =", s2)
}輸出結果:
s1 = [1 2 3 4 5]
s2 = [1 2 3 4 5 10]
s1 = [0 2 3 4 5]
s2 = [0 2 3 4 5 10]
由第一行和第二行結果看來,似乎這是指向兩個不同的陣列;但是當修改了s2,發現s1也跟著改變了,這又表明二者是指向同乙個陣列。到底真相是怎樣的呢?
執行以下**:
import (
"fmt"
"unsafe"
)type slice struct
func main()
s1 := array[:5]
s2 := append(s1, 10)
s2[0] = 0
// 把slice轉換成自定義的 slice struct
slice1 := (*slice)(unsafe.pointer(&s1))
fmt.printf("ptr:%v len:%v cap:%v \n", slice1.ptr, slice1.len, slice1.cap)
slice2 := (*slice)(unsafe.pointer(&s2))
fmt.printf("ptr:%v len:%v cap:%v \n", slice2.ptr, slice2.len, slice2.cap)
}輸出結果:
ptr:0xc04205e0a0 len:5 cap:20
ptr:0xc04205e0a0 len:6 cap:20
由結果可知:ptr指標儲存的是陣列中的首位址的值,並且這兩個值相同,所以s1和s2確實是指向同乙個底層陣列。
但是,這兩個陣列切片的元素不同,這個可以根據首位址和陣列切片長度len來確定不同的陣列切片應該包含哪些元素,因為s1和s2雖然指向同乙個底層陣列,但是二者的len不同。通過這個demo,也驗證了陣列切片傳參方式也是值傳遞。
執行以下**,思考與不擴容情況的不同之處,以及為什麼
func main()
s2 := append(s1, 10)
fmt.println("程式設計客棧s1 =", s1)
fmt.println("s2 =", s2)
s2[0] = 0
fmt.println("s1 =", s1)
fmt.println("s2 =", s2)
}輸出結果:
s1 = [1 2 3 4 5 6 7 8 9]
s2 = [1 2 3 4 5 6 7 8 9 10]
s1 = [1 2 3 4 5 6 7 8 9]
s2 = [0 2 3 4 5 6 7 8 9 10]
根據結果我們發現,修改s2後,s1並未改變,這說明當append()後,s1和s2並未指向同乙個底層陣列,這又是為什麼呢?
同樣,我們接著執行以下**:
import (
"fmt"
"unsafe"
)type slice程式設計客棧 struct
func main()
s2 := append(s1, 10)
fmt.println("s1 =", s1)
fmt.println("s2 =", s2)
s2[0] = 0
fmt.println("s1 =", s1)
fmt.println("s2 =", s2)
// 把slice轉換成自定義的 slice struct
slice1 := (*slice)(unsafe.pointer(&s1))
fmt.printf("ptr:%v len:%v cap:%v \n", slice1.ptr, slice1.len, slice1.cap)
slice2 := (*slice)(unsafe.pointer(&s2))
fmt.printf("ptr:%v len:%v cap:%v \n", slice2.ptr, slice2.len, slice2.cap)
}輸出結果:
s1 = [1 2 3 4 5 6 7 8 9]
s2 = [1 2 3 4 5 6 7 8 9 10]
s1 = [1 2 3 4 5 6 7 8 9]
s2 = [0 2 3 4 5 6 7 8 9 10]
ptr:0xc04207a000 len:9 cap:9
ptr:0xc04207c000 len:10 cap:18
由結果可知:append()後,s1和s2確實指向了不同的底層陣列,並且二者的陣列容量cap也不相同了。
過程是這樣的:當append()時,發現陣列容量不夠用,於是開闢了新的陣列空間,cap變為原來的兩倍,s2指向了這個新的陣列,所以當修改s2時,s1不受影響
本文標題: golang中的空slice案例
本文位址:
golang中slice的擴容機制
在golang中slice是乙個指向陣列的指標結構體。這個結構體有三個屬性 其概念為 動態陣列 及陣列的容量大小 cap 會隨著陣列的實際大小 size 變化而變化 擴容 擴容機制 如果切片的容量小於1024個元素,那麼擴容的時候slice的cap就翻番,乘以2 一旦元素個數超過1024個元素,則乘...
Golang中的Slice自動擴容機制
剛剛寫了乙個api用到了golang的slice,想著用slice這麼久了竟然不知道這到底是個什麼東西。只知道slice和常規陣列相比是可自動變長的,內部到底是怎麼實現的呢?於是今天就和同事一起研究了一下golang中slice的自動擴容機制,這裡採用的是golang1.12版本。閒話少說,直接開整...
分析golang的slice排序
今天寫 牽扯到給乙個slice排序的問題,發現go的sort包裡支援自定義排序,果斷拿來用了。sort.slice pricelist,func i,j int bool 上面這個是使用sort.slice 的例子。在此之前,先講講基礎的sort方法,type inte ce inte ce fun...