I recently tried appending two byte array slices in Go and came across some odd errors. My code is:
one:=make([]byte, 2)
two:=make([]byte, 2)
one[0]=0x00
one[1]=0x01
two[0]=0x02
two[1]=0x03
log.Printf("%X", append(one[:], two[:]))
three:=[]byte{0, 1}
four:=[]byte{2, 3}
five:=append(three, four)
And the errors are:
cannot use four (type []uint8) as type uint8 in append
cannot use two[:] (type []uint8) as type uint8 in append
Which taken into consideration the alleged robustness of Go's slices shouldn't be a problem:
http://code.google.com/p/go-wiki/wiki/SliceTricks
What am I doing wrong, and how should I go about appending two byte arrays?
There is no way in Golang to directly append an array to an array. Instead, we can use slices to make it happen. The following characteristics are important to note: Arrays are of a fixed size.
A byte in Go is an unsigned 8-bit integer. It has type uint8 . A byte has a limit of 0 – 255 in numerical range. It can represent an ASCII character.
The recommended solution to concatenate two or more byte arrays is using ByteArrayOutputStream . The idea is to write bytes from each of the byte arrays to the output stream, and then call toByteArray() to get the current contents of the output stream as a byte array.
Since slices are dynamically-sized, you can append elements to a slice using Golang's built-in append method. The first parameter is the slice itself, while the next parameter(s) can be either one or more of the values to be appended.
The Go Programming Language Specification
Appending to and copying slices
The variadic function
append
appends zero or more valuesx
tos
of typeS
, which must be a slice type, and returns the resulting slice, also of typeS
. The valuesx
are passed to a parameter of type...T
whereT
is the element type ofS
and the respective parameter passing rules apply.
append(s S, x ...T) S // T is the element type of S
Passing arguments to
...
parametersIf the final argument is assignable to a slice type
[]T
, it may be passed unchanged as the value for a...T
parameter if the argument is followed by...
.
You need to use []T...
for the final argument.
For your example, with the final argument slice type []byte
, the argument is followed by ...
,
package main import "fmt" func main() { one := make([]byte, 2) two := make([]byte, 2) one[0] = 0x00 one[1] = 0x01 two[0] = 0x02 two[1] = 0x03 fmt.Println(append(one[:], two[:]...)) three := []byte{0, 1} four := []byte{2, 3} five := append(three, four...) fmt.Println(five) }
Playground: https://play.golang.org/p/2jjXDc8_SWT
Output:
[0 1 2 3] [0 1 2 3]
append()
takes a slice of type []T
, and then a variable number of values of the type of the slice member T
. In other words, if you pass a []uint8
as the slice to append()
then it wants every subsequent argument to be a uint8
.
The solution to this is to use the slice...
syntax for passing a slice in place of a varargs argument. Your code should look like
log.Printf("%X", append(one[:], two[:]...))
and
five:=append(three, four...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With