![](/img/trans.png)
[英]For a Go slice, what is the difference between the slice and a full reslice of the slice?
[英]Go Slice - difference between [:n] and [n:]
轉到“切片”問題,請檢查以下內容,並在我遺漏某些東西時發表評論。
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
s = s[1:]
fmt.Println(s)
s = s[2:]
fmt.Println(s)
s = s[5:]
fmt.Println(s)
}
輸出:
[3 5 7 11 13] [7 11 13] panic: runtime error: slice bounds out of range
以上是合理的。
func main() {
s := []int{2, 3, 5, 7, 11, 13}
s = s[:1]
fmt.Println(s)
s = s[:2]
fmt.Println(s)
s = s[:5]
fmt.Println(s)
}
輸出:
[2] [2 3] [2 3 5 7 11]
這是否也應該使數組擺脫s = s [:2]的恐慌?
Go中的分片允許您在分片的末尾進行分片,只要它仍在底層陣列的容量范圍內即可。 您不能在該切片的開始之前進行切片,但是只要不超過最后分配的索引,就可以在該切片之后進行切片。
舉個例子, s[3:]
然后s[:3]
有效,但是s[4:]
然后s[:4]
會恐慌,因為您請求的是底層數組的索引4到7索引0-5。
這有點奇怪,但是它確實允許您通過執行slice = slice[:cap(slice)]
來最大化任何切片。
https://play.golang.org/p/Gq5xoXc3Vd
語言規范對此進行了說明,順便說一句。 我在下面對您使用的簡單切片符號進行了解釋(有一種替代方法也為新切片指定了最大索引)。
對於字符串,數組,指向數組或切片a的指針,主表達式
a[low : high]
構造一個子字符串或切片。 如果0 <=低<=高<= cap(a),則索引在范圍內,否則它們超出范圍。
在閱讀官方博客后,我只是想分享我的想法: https : //blog.golang.org/slices
這是Golang博客中的sliceHeader:
type sliceHeader struct {
Length int
ZerothElement *byte
}
現在,您聲明您的切片:
s := []int{2, 3, 5, 7, 11, 13}
我相信這樣做:
var array [6]int
slice := sliceHeader {
Length: 6,
ZerothElement: &array[0],
}
通過執行: s = s[:2]
,您有效地將sliceHeader的Length從6更改為2,因此sliceHeader將如下所示:
slice := sliceHeader {
Length: 2,
ZerothElement: &array[0],
}
請注意,ZerothElement仍指向內存中的同一位置。 因此,我們可以通過簡單地再次更改Length來將切片擴展回其原始形式s = s[:6]
。
現在,假設您沒有執行s = s[:2]
,而是執行了s = s[2:]
,您實際上所做的是通過從Length中減去2並向前移動ZerothElement兩個索引來隱藏前兩個元素,導致sliceHeader為:
slice := sliceHeader {
Length: 4,
ZerothElement: &array[2],
}
此時,您無法將切片恢復為原始形式,因為無法將切片擴展到ZerothElement之外。 好吧,如果假設您可以訪問ZerothElement之前的任何元素,該怎么辦? 然后我們的切片變為未定義,因為它可能是array[0...4]
, array[1...5]
或array[2...6]
。
是的,這就是為什么我認為[n:]和[:n]表現不同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.