There is not a perfect way to clone slices in Go - go101/go101 Wiki

Original URL: https://github.com/go101/go101/wiki/There-is-not-a-perfect-way-to-clone-slices-in-Go

I ever wrote a wiki article [[How to perfectly clone a slice?]] and got a conclusion that the perfect way is append(s[:0:0], s...). However, in fact, there is not a perfect slice clone way in Go.

Here, I list all the slice clone implementations and their respective drawbacks.

The implementations

1. Two-line make+copy

sClone = make([]T, len(s))
copy(sClone, s)

This is the fastest way since Go toolchain v1.15.

2. One-line make+append

sClone = append(make([]T, 0, len(s)), s...)

3. One-line append implementation A

sClone = append([]T(nil), s...)
// or
sClone = append([]T{}, s...)

4. One-line append implementation B

sClone = append(s[:0:0], s...)

This implementation has two advantage:

  1. make sure that the result sClone is nil if s is nil, and is not nil if s is not nil.
  2. don't need to import the containing package of type T even if T is declared in another package.

5. The verbose implementation

if s != nil {
	sClone = make([]T, len(s))
	copy(sClone, s)
} else {
	sClone = nil
}

6. The generics implementation

Generics to rescue?

import "slices"

sClone = slices.Clone(s)

Drawback: need to import a package.

But

in practice, we rarely need a perfect way to clone a slice. For a specified use case, it is very probably that one of the above ways could satisfy the need.