Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 如果切片的大小超过数组的大小,切片的元素将存储在哪里?_Go - Fatal编程技术网

Go 如果切片的大小超过数组的大小,切片的元素将存储在哪里?

Go 如果切片的大小超过数组的大小,切片的元素将存储在哪里?,go,Go,我从数组OrgArray创建一个切片,如下所示 orgArray:=[3] string{"00","01","02"} s := orgArray[:2] s = append(s,"03") s = append(s,"04") 其中“s”是我在数组“orgArray”上构建的切片 如果我打印Orgs和orgArray的大小 fmt.Println(s) //[00 01 03 04] fmt.Println(len(s),cap(s)) //4 6 fmt.Println(len(org

我从数组OrgArray创建一个切片,如下所示

orgArray:=[3] string{"00","01","02"}
s := orgArray[:2]
s = append(s,"03")
s = append(s,"04")
其中“s”是我在数组“orgArray”上构建的切片

如果我打印Orgs和orgArray的大小

fmt.Println(s) //[00 01 03 04]
fmt.Println(len(s),cap(s)) //4 6
fmt.Println(len(orgArray),cap(orgArray)) //3 3
len(s)是4,但len(orgArray)只有3为什么

追加时slice存储的额外元素在哪里

s := orgArray[:2]
由于从原始切片中提取两个元素,然后再附加两个元素,因此长度变为4。您可以在此处看到四个元素:

fmt.Println(s) //[00 01 03 04]
如果你想知道为什么容量是6,那是因为容量是以2的幂增加的。因此,如果您有一个容量为4的切片,并附加5个元素,那么容量将变为8。它与尝试为经常发生追加的片重新分配内存有关

由于从原始切片中提取两个元素,然后再附加两个元素,因此长度变为4。您可以在此处看到四个元素:

fmt.Println(s) //[00 01 03 04]
如果你想知道为什么容量是6,那是因为容量是以2的幂增加的。因此,如果您有一个容量为4的切片,并附加5个元素,那么容量将变为8。它与尝试为经常发生追加的片重新分配内存有关

如果s的容量不足以容纳附加值, append分配一个新的、足够大的基础数组,该数组适合 现有切片元素和附加值。否则,, append重新使用基础数组

有关
append
内置函数如何工作的更多详细信息,请阅读以下博文:

此外,请参阅此StackOverflow答案,其中说明了重新分配容量的计算:

比如说,

package main

import "fmt"

func main() {
    orgArray := [3]string{"00", "01", "02"}
    fmt.Println("orgArray:", &orgArray[0], len(orgArray), orgArray)
    s := orgArray[:2]
    fmt.Println("       s:", &s[0], len(s), cap(s), s)
    s = append(s, "03")
    fmt.Println("       s:", &s[0], len(s), cap(s), s)
    s = append(s, "04")
    fmt.Println("       s:", &s[0], len(s), cap(s), s)
    fmt.Println("orgArray:", &orgArray[0], len(orgArray), orgArray)
}
输出:

orgArray: 0x1052f2c0 3 [00 01 02]
       s: 0x1052f2c0 2 3 [00 01]
       s: 0x1052f2c0 3 3 [00 01 03]
       s: 0x1051a120 4 6 [00 01 03 04]
orgArray: 0x1052f2c0 3 [00 01 03]

如果s的容量不足以容纳附加值, append分配一个新的、足够大的基础数组,该数组适合 现有切片元素和附加值。否则,, append重新使用基础数组

有关
append
内置函数如何工作的更多详细信息,请阅读以下博文:

此外,请参阅此StackOverflow答案,其中说明了重新分配容量的计算:

比如说,

package main

import "fmt"

func main() {
    orgArray := [3]string{"00", "01", "02"}
    fmt.Println("orgArray:", &orgArray[0], len(orgArray), orgArray)
    s := orgArray[:2]
    fmt.Println("       s:", &s[0], len(s), cap(s), s)
    s = append(s, "03")
    fmt.Println("       s:", &s[0], len(s), cap(s), s)
    s = append(s, "04")
    fmt.Println("       s:", &s[0], len(s), cap(s), s)
    fmt.Println("orgArray:", &orgArray[0], len(orgArray), orgArray)
}
输出:

orgArray: 0x1052f2c0 3 [00 01 02]
       s: 0x1052f2c0 2 3 [00 01]
       s: 0x1052f2c0 3 3 [00 01 03]
       s: 0x1051a120 4 6 [00 01 03 04]
orgArray: 0x1052f2c0 3 [00 01 03]

slice的结构如下所示:

struct Slice
{ // must not move anything
 byte* array; // actual data
 uintgo len; // number of elements
 uintgo cap; // allocated number of elements
};
而在你的例子中。解释如下:

orgArray := [3]string{"00", "01", "02"}
s := orgArray[:2]
fmt.Println(len(s),cap(s))  //2,3 s is pointer to orgArray
s = append(s, "03")
fmt.Println(len(s),cap(s))  //3,3 cap is enough. s is pointer to orgArray
s = append(s, "04")
fmt.Println(len(s),cap(s))  //4,6 cap is not enough. regenerate array. then s point to the new array.

slice的结构如下所示:

struct Slice
{ // must not move anything
 byte* array; // actual data
 uintgo len; // number of elements
 uintgo cap; // allocated number of elements
};
而在你的例子中。解释如下:

orgArray := [3]string{"00", "01", "02"}
s := orgArray[:2]
fmt.Println(len(s),cap(s))  //2,3 s is pointer to orgArray
s = append(s, "03")
fmt.Println(len(s),cap(s))  //3,3 cap is enough. s is pointer to orgArray
s = append(s, "04")
fmt.Println(len(s),cap(s))  //4,6 cap is not enough. regenerate array. then s point to the new array.

但底层数组orgArray的大小只有3。我在数组orgArray上构建了切片“s”。切片不是数组-切片的大小是动态的,因此在附加对象时它会自动增长。与C#中的列表非常相似。@AlexMathew:
orgArray
不够大,因此为
s
分配了一个新的底层数组。有关详细信息,请参见我的答案。但是基础数组orgArray的大小只有3。我在数组orgArray上构建了切片“s”。切片不是数组-切片的大小是动态的,因此在附加对象时它会自动增长。与C#中的列表非常相似。@AlexMathew:
orgArray
不够大,因此为
s
分配了一个新的底层数组。有关详细信息,请参阅我的答案。