-------------------------------------------- On Tue, 1/10/17, Marvin Renich <m...@renich.org> wrote:
Subject: Re: [go-nuts] Reset Slice with Make Every Time? To: "golang-nuts" <golang-nuts@googlegroups.com> Date: Tuesday, January 10, 2017, 5:29 PM * Tomi Häsä <tomi.h...@gmail.com> [170110 02:23]: > On Tuesday, January 10, 2017 at 1:49:37 AM UTC+2, kortschak wrote: > > On Mon, 2017-01-09 at 15:12 -0800, Tomi Häsä wrote: > > > Is this the correct way of resetting a slice? I mean do I always > > > need to use make to reset a slice? > > > > > > // initialize slice > > > onearea Area = Area{} > > > group []Area = make( []Area, 0, MAX ) > > > > > > // add stuff to slice > > > group = append( group, onearea ) > > > > > > // reset slice > > > group = make( []Area, 0, MAX ) > > > > group = group[:0] > > > > > Using nil to reset a slice doesn't seem to be wise as the capacity > > > does not stay with MAX, but it will decrease to 2 in my program. > > > > > > group = nil > > > > > > Full code here: https://github.com/tomihasa/unicodetest > > By the way, what happens to the old data I used with the previous make > command? I'm not sure if these were mentioned earlier in the thread, but both https://blog.golang.org/slices and https://blog.golang.org/go-slices-usage-and-internals give some really good info on this. The abbreviated answer is to think of a slice as a view into its backing array. As long as a slice (or other variable) refers to the backing array or one of its elements, the garbage collector will not reclaim any of the backing array. So, even doing group = group[1:] will not allow the GC to reclaim the memory for the old group[0]. If the elements of the slice (and therefore of the backing array) are simple values, such as ints, or structs of simple values, doing group = group[:0] will reset the slice to empty without changing its current capacity and without reallocating the memory for its backing array. If, however, the slice elements contain pointers, maps, channels, or other slices, then the memory referred to by those items will not be reclaimed, even though group appears to not refer to them. As you append to group the second time around, those elements will be overwritten, and the memory referred to by the old values will be able to be reclaimed by the GC. Example: type LargeStruct struct { /* lots of fields */ } func NewLargeStruct(i int) (ls *LargeStruct) { /* does what's needed */ } type SmallStruct struct { ls *LargeStruct } var small []SmallStruct = make([]SmallStruct, 0, 50) for i := 0; i < 10; i++ { small = append(small, SmallStruct{NewLargeStruct(i)}) } small[:0] small is now an empty slice with capacity 50, but none of the memory allocated for the ten instances of LargeStruct is able to be reclaimed by the GC. This is because the backing array still contains the pointers to all of the LargeStruct's allocated in the loop. Now do small = append(small, SmallStruct{NewLargeStruct(41)}) small = append(small, SmallStruct{NewLargeStruct(42)}) and the memory allocated by NewLargeStruct(0) and NewLargeStruct(1) in the earlier loop can be reclaimed (assuming they are not referenced elsewhere). On the other hand, replacing small[:0] in the above code by small = make([]SmallStruct, 0, 50) will allocate a new backing array and will allow the old backing array as well as all of the LargeStruct's to be reclaimed. Which is better will depend on your application. ...Marvin -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.arlamentul de la Bucuresti a suspendat activitatea P.C.R. care sustinuse fatis -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.