這篇文章跟大家探討一下slice在Go中的使用,一起看看下面這段程式
package main
import (
"fmt"
)
func main() {
var array [10]int
var slice = array[5:6]
fmt.Println("lenth of slice: ", len(slice))
fmt.Println("capacity of slice: ", cap(slice))
fmt.Println(&slice[0] == &array[5])
}
- 這段程式我想說的是:main函式中定義了一個10個長度的整型陣列array,然後定義了一個切片slice,切取陣列的第6個元 素,最後列印slice的長度和容量,判斷切片的第一個元素和陣列的第6個元素地址是否相等。
- 大家想想切片的第一個元素和陣列的第6個元素相等嗎,或許可以跑跑這段程式證明一下在往下面看結果,好了我也不賣關子啦,上面程式中slice跟據陣列array建立,與陣列共享儲存空間,slice起始位置是array[5],長度為1,容量為5, slice[0]和array[5]地址相同。
接下來大家看看這段程式,試著自己跑一下程式,動手實踐是最好的老師
package main
import (
"fmt"
)
func AddElement(slice []int, e int) []int {
return append(slice, e)
}
func main() {
var slice []int
slice = append(slice, 1, 2, 3)
newSlice := AddElement(slice, 4)
fmt.Println(&slice[0] == &newSlice[0])
}
- 上面這段我想表達的是函式AddElement()接受一個切片和一個元素,把元素append進切片中,並返回切片。main()函式中定 義一個切片,並向切片中append 3個元素,接著呼叫AddElement()繼續向切片append進第4個元素同時定義一個 新的切片newSlice。最後判斷新切片newSlice與舊切片slice是否共用一塊儲存空間
- 這段程式相信很多小夥伴都覺得append會有可能觸發舊Slice的擴容,又不敢特別肯定吧,接著往下看”有可能”變為”肯定”啦:
1.append函式執行時會判斷切片容量是否能夠存放新增元素,如果不能,則會重新申請儲存空間,新儲存空間將是原來的2倍或1.25倍(取決於擴充套件原空間大小),本例中實際執行了兩次append操作,第一次空間增長到4,所以第二次append不會再擴容,所以新舊兩個切片將共用一塊儲存空間。程式會輸出”true”。
接著往下繼續看這段程式會怎樣輸出,可以思考一下或者跑跑程式:
package main
import (
"fmt"
)
func main() {
orderLen := 5
order := make([]uint16, 2 * orderLen)
pollorder := order[:orderLen:orderLen]
lockorder := order[orderLen:][:orderLen:orderLen]
fmt.Println("len(pollorder) = ", len(pollorder))
fmt.Println("cap(pollorder) = ", cap(pollorder))
fmt.Println("len(lockorder) = ", len(lockorder))
fmt.Println("cap(lockorder) = ", cap(lockorder))
}
跑完上面的程式後帶著疑問接著往下看會更好,整個人有一種豁然開朗的感覺,不信可以試試:
- 程式中定義一個長度為10的切片order,pollorder和lockorder分別是對order切片做了order[start,stop,max]操作生成的切片,最後程式分別列印pollorder和lockorder的容量和長度。
- order[start,stop,max]的意思是對order進行切片,新切片範圍是[start, stop),新切片容量是max。order長度為2倍的orderLen,pollorder切片指的是order的前半部分切片,lockorder指的是order的後半部分切片,即原order分成了兩段。所以,pollorder和lockerorder的長度和容量都是orderLen,即5。
這篇文章對Slice的一些使用講解就在這裡了,希望幫到有需要的夥伴吧,更多關於Slice的使用歡迎留言告知探討
本作品採用《CC 協議》,轉載必須註明作者和本文連結