Go Slice - [:n]和[n:]之间的区别

时间:2016-08-15 18:23:06

标签: arrays go slice

Go Slice问题,如果我遗漏了某些内容,请查看以下内容并发表评论。

   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]?

获得数组超出范围的恐慌

1 个答案:

答案 0 :(得分:0)

我只是想在阅读官方博客后分享我的想法: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的长度从6更改为2,因此您的sliceHeader将如下所示:

slice := sliceHeader {
    Length:        2,
    ZerothElement: &array[0],
}

请注意,ZerothElement仍指向内存中的相同位置。因此,只需再次更改长度,我们就可以将切片扩展回原始形式s = s[:6]

现在,让我们说你没有做s = s[:2]而是做s = s[2:],你实际做的是通过从长度中减去2来隐藏前两个元素并将ZerothElement移动两个指数前进,产生一个sliceHeader:

slice := sliceHeader {
    Length:        4,
    ZerothElement: &array[2],   
}

此时,您无法将切片恢复为其原始形式,因为无法将切片扩展到ZerothElement之外。好的,如果假设您可以在ZerothElement之前访问任何元素,该怎么办?然后我们的切片变得未定义,因为它可能是array[0...4]array[1...5]array[2...6]

所以是的,这就是我认为[n:]和[:n]表现不同的原因。