如何判断append是否创建了一个新的底层数组

问题描述 投票:-3回答:2

有可能判断append内置函数是否创建了一个新的底层数组?

arrays go slice
2个回答
0
投票

您可以查找第一个元素的内存指针。

如果内部容量按照两个功率步骤按比例放大,则会发生变化。

package main

import (
    "fmt"
)

func main() {
    sl := make([]int, 0, 4)
    sl = append(sl, []int{1,2}...)  
    fmt.Printf("%#v<-%v # same pointer address to the slice length 2 with capacity 4\n", &sl[0], len(sl))
    sl = append(sl, []int{1,2}...)  
    fmt.Printf("%#v<-%v # same pointer address to the slice length 2 with capacity 4\ncapacity will change from the next append on:\n", &sl[0], len(sl))
    for i:=0; i<10; i++{
        sl = append(sl, 1)
        fmt.Printf("%#v<-len(%v) cap(%v)\n", &sl[0], len(sl), cap(sl))
    }
    for i:=0; i<10; i++{
        sl = append(sl, sl...)
        fmt.Printf("%#v<-len(%v) cap(%v)\n", &sl[0], len(sl), cap(sl))
    }
}

will print:
(*int)(0x414020)<-2 # same pointer address to the slice length 2 with capacity 4
(*int)(0x414020)<-4 # same pointer address to the slice length 2 with capacity 4
capacity will change from the next append on:
(*int)(0x450020)<-len(5) cap(8)
(*int)(0x450020)<-len(6) cap(8)
(*int)(0x450020)<-len(7) cap(8)
(*int)(0x450020)<-len(8) cap(8)
(*int)(0x432080)<-len(9) cap(16)
(*int)(0x432080)<-len(10) cap(16)
(*int)(0x432080)<-len(11) cap(16)
(*int)(0x432080)<-len(12) cap(16)
(*int)(0x432080)<-len(13) cap(16)
(*int)(0x432080)<-len(14) cap(16)
(*int)(0x456000)<-len(28) cap(32)
(*int)(0x458000)<-len(56) cap(64)
(*int)(0x45a000)<-len(112) cap(128)
(*int)(0x45c000)<-len(224) cap(256)
(*int)(0x45e000)<-len(448) cap(512)
(*int)(0x460000)<-len(896) cap(1024)
(*int)(0x462000)<-len(1792) cap(2048)
(*int)(0x464000)<-len(3584) cap(4096)
(*int)(0x468000)<-len(7168) cap(8192)
(*int)(0x470000)<-len(14336) cap(16384)

(注意:如果查看切片的unsafe.Pointer,则更改模式不太明显)


3
投票

当然,比较之前和之后的容量:

before := cap(myArray)
myArray = append(myArray, newValue)
after := cap(myArray)
fmt.Printf("before: %d, after: %d", before, after)

更好的问题是,你为什么需要?您的代码真的不应该关心是否创建了新的后备阵列。

游乐场演示:https://play.golang.org/p/G_ZfrLfEpWb

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