Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use Go append with two []byte slices or arrays?

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?

like image 369
ThePiachu Avatar asked Dec 11 '11 02:12

ThePiachu


People also ask

How do you append to an array in Go?

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.

What does [] byte mean in Go?

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.

How do you add two byte arrays?

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.

How do I append to a slice in Golang?

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.


2 Answers

The Go Programming Language Specification

Appending to and copying slices

The variadic function append appends zero or more values x to s of type S, which must be a slice type, and returns the resulting slice, also of type S. The values x are passed to a parameter of type ...T where T is the element type of S and the respective parameter passing rules apply.

append(s S, x ...T) S // T is the element type of S

Passing arguments to ... parameters

If 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] 
like image 73
peterSO Avatar answered Oct 11 '22 18:10

peterSO


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...) 
like image 25
Lily Ballard Avatar answered Oct 11 '22 18:10

Lily Ballard