

Using NEW, instead of MAKE, to create slice
source link: https://dev.to/freakynit/using-new-instead-of-make-to-create-slice-17bl
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

As we know, slices in golang are reference types, and hence, need make
to initialize them.
func main() {
a := make([]int32, 0)
a = append(a, 10, 20, 30)
fmt.Println(len(a), cap(a), reflect.ValueOf(a).Kind())
}
>>> 3 4 slice
But, can we use new
to make slices? It's meant to be used for value types only. So how can it work here??
Let's see
func main() {
a := new([]int32)
}
Does this↑ work? Yes. It does. So what is the difference?
The difference is that this gives you a pointer, as is the case anytime you use new
. Thus to actually use it, you have to dereference it everytime.
Example:
func main() {
a := new([]int32)
*a = append(*a, 10, 20, 30)
fmt.Println(len(*a), cap(*a), reflect.ValueOf(*a).Kind())
}
>>> 3 4 slice
Another simple change you can do is to dereference it immediately after creation. This will save you the effort of dereferencing it every other time.
func main() {
a := *new([]int32)
a = append(a, 10, 20, 30)
fmt.Println(len(a), cap(a), reflect.ValueOf(a).Kind())
}
>>> 3 4 slice
There's another important concept:
Every time you append to a slice, it gives you a new slice with a different address (though it points to same underlying array)
Let's see this with same example:
func main() {
a := make([]int32, 0)
fmt.Printf("%p\n", a)
a = append(a, 10, 20, 30)
fmt.Printf("%p\n", a)
a = append(a, 10, 20, 30)
fmt.Printf("%p\n", a)
fmt.Println(len(a), cap(a), reflect.ValueOf(a).Kind())
}
>>> 0x116bea0
>>> 0xc0000220e0
>>> 0xc00001c100
>>> 6 8 slice
You see, all 3 addresses are different.
But, can we keep the addresses same even after append? Well yes!! It's here your NEW
approach comes into place. See this:
func main() {
a := new([]int32)
fmt.Printf("%p\n", a)
*a = append(*a, 10, 20, 30)
fmt.Printf("%p\n", a)
*a = append(*a, 10, 20, 30)
fmt.Printf("%p\n", a)
fmt.Println(len(*a), cap(*a), reflect.ValueOf(*a).Kind())
}
>>> 0xc00011c030
>>> 0xc00011c030
>>> 0xc00011c030
>>> 6 8 slice
You see? All 3 addresses remain same!!!
That's all folks for now?
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK