Reputation: 4225
I create a slice from the array OrgArray as follows
orgArray:=[3] string{"00","01","02"}
s := orgArray[:2]
s = append(s,"03")
s = append(s,"04")
Where 's' is my slice I built up on the array 'orgArray'
If I print the size of the s and 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) is 4 but len(orgArray) is only 3 why?
Where is the extra elements of slice is storing while appending?
Upvotes: 1
Views: 314
Reputation: 166569
The Go Programming Language Specification
Appending to and copying slices
If the capacity of s is not large enough to fit the additional values, append allocates a new, sufficiently large underlying array that fits both the existing slice elements and the additional values. Otherwise, append re-uses the underlying array.
For additional details on how the append
built-in function works, read this blog post:
Arrays, slices (and strings): The mechanics of 'append'
Also, see this StackOverflow answer, which illustrates the reallocation capacity calculation:
For example,
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)
}
Output:
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]
Upvotes: 5
Reputation: 51
slice's struct is like this:
struct Slice
{ // must not move anything
byte* array; // actual data
uintgo len; // number of elements
uintgo cap; // allocated number of elements
};
while in your example. explain as follow:
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.
Upvotes: 2
Reputation: 5380
s := orgArray[:2]
Since you take two elements from the original slice and then append two more the length becomes 4. You can see the four elements here:
fmt.Println(s) //[00 01 03 04]
If you wonder why the capacity is 6 it's because capacity is increased in power of 2. So if you have a slice with capacity 4 and append 5 elements the capacity will become 8. It is related to trying to re-allocate the memory for the slice that often when append occurs.
Upvotes: 1