I'm working on the creating a Java library that deals with management of Arrays. Is there an equivalent of Arrays.copyOfRange in Go?
A simple one-liner would be (index check omitted):
func copyOfRange(src []byte, from, to int) []byte {
return append([]byte(nil), src[from:to]...)
}
A simple slice expression "almost" does the job, but since Java's Arrays.copyOfRange()
returns a copy independent from the source, we need to copy the slicing result to a new slice (because the result of slicing will share the backing array).
We can do that by allocating one with make()
, and use the builtin copy()
, or simply use append()
to append it to an empty or nil
slice, which will take care of the allocation and copying.
Example using the above function:
src := []byte{0, 1, 2, 3, 4, 5}
dst := copyOfRange(src, 2, 4)
fmt.Println(dst)
Output (try it on the Go Playground):
[2 3]
For completeness, this is how it would look like with make()
and copy()
:
func copyOfRange2(src []byte, from, to int) []byte {
src = src[from:to]
dst := make([]byte, len(src))
copy(dst, src)
return dst
}
One thing to note here: the builtin append()
allocates more space than needed, thinking of future growth. So if you don't plan to "grow" the returned slice, copyOfRange2()
is a better option.
See this comparison:
dst := copyOfRange(src, 2, 4)
fmt.Println(dst, cap(dst))
dst = copyOfRange2(src, 2, 4)
fmt.Println(dst, cap(dst))
Output (try it on the Go Playground):
[2 3] 8
[2 3] 2
As you can see, append()
(inside copyOfRange()
) allocated a backing array with a size of 8
, while in our copyOfRange2()
we explicitly allocated a slice (and backing array) of size 2
.