go version)?Go 1.10.1
Yes.
go env)?darwin/amd64
When you call a variadic func with a byte slice, calling cap is creating different results.
x := []byte("a")
// without this, Println prints 32 32
func(a ...[]byte) {}(x)
fmt.Println(cap(x), cap([]byte("a"))) // 8 32
https://play.golang.org/p/ZcrsUNAbPZr
32 32
8 32
This is an implementation detail. You're seeing differences in how the compiler chooses to implement things.
The language doesn't guarantee the the capacity on a conversion from a string.
See #24163 and #24204.
For now, if the capacity is important for your application, use make and set the capacity explicitly.
Thanks @bradfitz I just found it and wanted to let you know. It's not that I was using this in my application, I was just experimenting with it because of curiosity.
Do you know which part of the implementation changes the cap of the passed [][]byte?
If the backing array for the slice is allocated on the heap, it gets its capacity by rounding up to the next object size, in this case 8.
If the backing array for the slice is allocated on the stack, it gets its capacity from the temporary buffer we allocate on the stack, which has capacity 32.
So the difference in your two cases is whether escape analysis decides to allocate the backing array on the heap or the stack.
See src/runtime/string.go:stringtoslicebyte and friends.
@randall77 That's great, you've explained all in detail! I was looking for its assembly output and I was suspecting of stringtoslicebyte, tmpBuf, and rawbyteslice etc. Thanks for validating it!
For clarity, I think that the spec might say something about this: "Capacity of a slice is implementation specific when it's not specified explicitly by a make call.".
@inancgumus, that's what #24163 is about.
Ah OK, sorry, I read the whole conversation now. Thank you.
Most helpful comment
This is an implementation detail. You're seeing differences in how the compiler chooses to implement things.
The language doesn't guarantee the the capacity on a conversion from a string.
See #24163 and #24204.
For now, if the capacity is important for your application, use
makeand set the capacity explicitly.