6

I'm working with a HID driver, and this driver reads onto a []byte buffer one of a few different reports. When I use hex.EncodeToString(buffer), it will return a string looking like either 0000 or 0100 or 0200, etc. I want to check, using a switch, against the input from the HID device, and so I want to predefine these possibilities, up outside the main(), how should I proceed?

I've tried these possibilities:

var LEFT []byte = []byte('0000')
// or
var LEFT []byte = `0000`
// or 
var LEFT []byte = '0000'
// or
var LEFT []byte = '\x00\x00' // from the %q Printf verb

The alternative is that I call hex.DecodeString("0000") inside the main() function.

Edit

A note on the solution offered, the EncodeToString hex 0000 or 0100 is not four bytes but rather two:

"\x01" == "01" == '1'

so I can use, in order to get 0100, or 0200, as suggested:

var LEFT []byte{1,0}
// or 
var LEFT []byte("\x01\x00")
icza
  • 389,944
  • 63
  • 907
  • 827
Nevermore
  • 7,141
  • 5
  • 42
  • 64
  • _"... but this involves error checking, and I was hoping to set them aside."_ If you want to work / program in Go, get used to error checking. Else you'll make your (Go) life miserable... – icza Sep 06 '16 at 19:12
  • 1
    Oh and I do love the error checking, I meant, I didn't want to error check for a DecodeString for which I was sure to succeed in, that is, I wanted to define the []byte before compiling, with a value I was already sure would not give me an error. – Nevermore Sep 07 '16 at 02:41
  • 1
    If you know it won't fail, you may provide a `MustDecode()` helper function. For details see answer [Go: multiple value in single-value context](http://stackoverflow.com/a/28233172/1705598). – icza Sep 07 '16 at 06:55

3 Answers3

10

Use the following:

var (
    left = []byte{0, 0}
    right = []byte{1, 0}
    // ... and so on
)

If you want to write it on hex:

var (
    left = []byte{0x00, 0x00}
    right = []byte{0x01, 0x00}
    // ... and so on
)

You can also convert a string to a []byte:

var (
    left = []byte("\x00\x00")
    right = []byte("\x01\x00")
)

Use these variables in a switch statement like this:

switch {
case bytes.Equal(v, left):
    fmt.Println("left")
case bytes.Equal(v, right): 
    fmt.Println("right"
}

It looks like you are working with 2 byte numbers encoded in little-endian format. If so, you can decode the bytes to an integer:

const (
    left = 0
    right = 1
)

switch binary.LittleEndian.Uint16(byteSlice) {
case left:
    fmt.Println("left")
case right:
    fmt.Println("right")
}
Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242
2

Defining a []byte is easiest and recommended to do with a Composite literal as Mellow Marmot suggested. Note that the composite literal also has the advantage that you may use optional indices in the literal, and values for "missing" indices will be the zero value of the element type (0 in case of byte). And also if you need a []byte full of zeros, you don't need to list the elements, you can just make an "empty" slice.

So for example you may also create your slices like this:

var (
    left  = make([]byte, 2) // will be [0, 0]
    right = []byte{1: 1}    // will be [0, 1]
)

func main() {
    fmt.Println(left, right)
}

Output (try it on the Go Playground):

[0 0] [0 1]

Also know that string values can be directly converted to []byte which results in the byte sequence of the UTF-8 encoded bytes of the string (this is how Go stores strings in memory).

So if you can provide a string literal which has the UTF-8 encoded byte sequence that you need, you can simply convert it to []byte. And since interpreted string literals may contain escape sequences, it's easier than you think:

The three-digit octal (\nnn) and two-digit hexadecimal (\xnn) escapes represent individual bytes of the resulting string...

So you may also specify your byte values encoded in a string like this:

// With octal escapes
var (
    left  = []byte("\000\000")
    right = []byte("\001\000")
)

// With hexa escapes
var (
    left2  = []byte("\x00\x00")
    right2 = []byte("\x01\x00")
)

func main() {
    fmt.Println(left, right)
    fmt.Println(left2, right2)
}

Output (try it on the Go Playground):

[0 0] [1 0]
[0 0] [1 0]

See related questions:

GO explicit array initialization

Keyed items in golang array initialization

Community
  • 1
  • 1
icza
  • 389,944
  • 63
  • 907
  • 827
0

You can't use []byte in switch because slices are not comparable, strings are. So seams just

const LEFT = `0000`
Uvelichitel
  • 8,220
  • 1
  • 19
  • 36