golang中的空slice案例

2022-09-21 17:06:10 字數 3672 閱讀 5851

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...