延长长度并保持价值

问题描述 投票:1回答:1

我跟着Go去了解GOLANG。

我在这一步有一个问题:https://tour.golang.org/moretypes/11

  package main

  import "fmt"

  func main() {
    s := []int{2, 3, 5, 7, 11, 13}
    printSlice(s)

    // Step1 Slice the slice to give it zero length.
    s = s[:0]
    printSlice(s)

    // Step2 Extend its length.
    // Why after extend the length of the slice, the value in this slice is still  [2 3 5 7]
    s = s[:4]
    printSlice(s)

    // Step 3 Drop its first two values.
    s = s[2:]
    printSlice(s)
  }

  func printSlice(s []int) {
    fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
  }

输出:

len=6 cap=6 [2 3 5 7 11 13]
len=0 cap=6 []
len=4 cap=6 [2 3 5 7]
len=2 cap=4 [5 7]

为什么在第二步延长切片长度后,此切片中的值仍为[2 3 5 7]?我认为这个切片中的值是[0 0 0 0]因为我在第一步切片了原始切片。

我还有另一个问题是,为什么第三步可以改变切片的容量,但第一步不能。

go
1个回答
2
投票

因为第一次扩展不会改变切片的指针地址。所以s也指向[2 3 5 7 11 13]地址。

package main

import (
    "fmt"
    "unsafe"
)

func main() {
    s := []int{2, 3, 5, 7, 11, 13}
    printSlice(s)

    // Slice the slice to give it zero length.
    s = s[:0]
    printSlice(s)

    // Extend its length.
    s = s[:4]
    printSlice(s)

    // Drop its first two values.
    s = s[2:]
    printSlice(s)
}

func printSlice(s []int) {
    fmt.Printf("len=%d cap=%d %v array ptr: %v \n", len(s), cap(s), s,(*unsafe.Pointer)(unsafe.Pointer(&s)))
}

终端显示:

len=6 cap=6 [2 3 5 7 11 13] array ptr: 0xc04200a2a0
len=0 cap=6 [] array ptr: 0xc04200a2a0
len=4 cap=6 [2 3 5 7] array ptr: 0xc04200a2a0
len=2 cap=4 [5 7] array ptr: 0xc04200a2b0

你看,第三步改变了ptr地址,因为第一项改变了。所以你知道...

© www.soinside.com 2019 - 2024. All rights reserved.