定义一个不使用hex.DecodeString的[]byte。

huangapple go评论82阅读模式
英文:

Define a []byte without hex.DecodeString

问题

我正在使用一个HID驱动程序,这个驱动程序会读取一个[]byte缓冲区中的几个不同的报告。当我使用hex.EncodeToString(buffer)时,它会返回一个类似于000001000200的字符串。我想使用一个switch语句来检查来自HID设备的输入,并且我想在main()之外预定义这些可能性,我应该如何操作?

我尝试了以下几种可能性:

var LEFT []byte = []byte("0000")
// 或者
var LEFT []byte = `0000`
// 或者
var LEFT []byte = []byte{'0', '0', '0', '0'}
// 或者
var LEFT []byte = []byte("\x00\x00") // 使用%q Printf动词

另一种方法是在main()函数内部调用hex.DecodeString("0000")

编辑

关于提供的解决方案,EncodeToString将十六进制的00000100转换为两个字节而不是四个字节:

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

所以,为了得到0100或0200,你可以使用以下方式:

var LEFT []byte = []byte{1, 0}
// 或者
var LEFT []byte = []byte("\x01\x00")
英文:

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:

<!-- language: lang-golang -->

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

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

Edit

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

&quot;\x01&quot; == &quot;01&quot; == &#39;1&#39;

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

<!-- language: lang-golang -->

var LEFT []byte{1,0}
// or 
var LEFT []byte(&quot;\x01\x00&quot;)

答案1

得分: 10

使用以下代码:

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

如果你想以十六进制形式写入:

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

你也可以将字符串转换为[]byte

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

switch语句中使用这些变量,像这样:

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

看起来你正在使用小端格式编码的2字节数字。如果是这样,你可以将字节解码为整数,使用encoding/binary包中的LittleEndian函数:

const (
    left = 0
    right = 1
)

switch binary.LittleEndian.Uint16(byteSlice) {
case left:
    fmt.Println("left")
case right:
    fmt.Println("right")
}

希望对你有帮助!

英文:

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(&quot;\x00\x00&quot;)
    right = []byte(&quot;\x01\x00&quot;)
)

Use these variables in a switch statement like this:

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

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(&quot;left&quot;)
case right:
    fmt.Println(&quot;right&quot;)
}

答案2

得分: 2

定义一个[]byte最简单且推荐的方法是使用复合字面量,就像Mellow Marmot建议的那样。请注意,复合字面量还具有一个优点,即您可以在字面量中使用可选索引,并且对于“缺失”的索引值将是元素类型的零值(在byte的情况下为0)。而且,如果您需要一个全是零的[]byte,您不需要列出元素,只需使用make创建一个“空”的切片。

所以例如,您也可以像这样创建您的切片:

var (
    left  = make([]byte, 2) // 将会是 [0, 0]
    right = []byte{1: 1}    // 将会是 [0, 1]
)

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

输出结果(在Go Playground上尝试):

[0 0] [0 1]

还要知道,string值可以直接转换为[]byte,这将得到string的UTF-8编码字节序列(这是Go在内存中存储字符串的方式)。

因此,如果您可以提供一个string字面量,其中包含您需要的UTF-8编码字节序列,您可以简单地将其转换[]byte。而且,由于解释型的string字面量可以包含转义序列,所以比您想象的要简单:

三位数的八进制(\nnn)和两位数的十六进制(\xnn)转义表示结果字符串的各个字节...

因此,您也可以像这样在string中指定编码的字节值:

// 使用八进制转义
var (
    left  = []byte("
// 使用八进制转义
var (
    left  = []byte("\000\000")
    right = []byte("\001\000")
)

// 使用十六进制转义
var (
    left2  = []byte("\x00\x00")
    right2 = []byte("\x01\x00")
)

func main() {
    fmt.Println(left, right)
    fmt.Println(left2, right2)
}
0
// 使用八进制转义
var (
    left  = []byte("\000\000")
    right = []byte("\001\000")
)

// 使用十六进制转义
var (
    left2  = []byte("\x00\x00")
    right2 = []byte("\x01\x00")
)

func main() {
    fmt.Println(left, right)
    fmt.Println(left2, right2)
}
0"
)
right = []byte("
// 使用八进制转义
var (
    left  = []byte("\000\000")
    right = []byte("\001\000")
)

// 使用十六进制转义
var (
    left2  = []byte("\x00\x00")
    right2 = []byte("\x01\x00")
)

func main() {
    fmt.Println(left, right)
    fmt.Println(left2, right2)
}
1
// 使用八进制转义
var (
    left  = []byte("\000\000")
    right = []byte("\001\000")
)

// 使用十六进制转义
var (
    left2  = []byte("\x00\x00")
    right2 = []byte("\x01\x00")
)

func main() {
    fmt.Println(left, right)
    fmt.Println(left2, right2)
}
0"
)
) // 使用十六进制转义 var ( left2 = []byte("\x00\x00") right2 = []byte("\x01\x00") ) func main() { fmt.Println(left, right) fmt.Println(left2, right2) }

输出结果(在Go Playground上尝试):

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

相关问题请参考:

https://stackoverflow.com/questions/38783260/go-explicit-array-initialization

https://stackoverflow.com/questions/36302441/keyed-items-in-golang-array-initialization

英文:

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(&quot;
// With octal escapes
var (
left  = []byte(&quot;\000\000&quot;)
right = []byte(&quot;\001\000&quot;)
)
// With hexa escapes
var (
left2  = []byte(&quot;\x00\x00&quot;)
right2 = []byte(&quot;\x01\x00&quot;)
)
func main() {
fmt.Println(left, right)
fmt.Println(left2, right2)
}
0
// With octal escapes
var (
left  = []byte(&quot;\000\000&quot;)
right = []byte(&quot;\001\000&quot;)
)
// With hexa escapes
var (
left2  = []byte(&quot;\x00\x00&quot;)
right2 = []byte(&quot;\x01\x00&quot;)
)
func main() {
fmt.Println(left, right)
fmt.Println(left2, right2)
}
0&quot;) right = []byte(&quot;
// With octal escapes
var (
left  = []byte(&quot;\000\000&quot;)
right = []byte(&quot;\001\000&quot;)
)
// With hexa escapes
var (
left2  = []byte(&quot;\x00\x00&quot;)
right2 = []byte(&quot;\x01\x00&quot;)
)
func main() {
fmt.Println(left, right)
fmt.Println(left2, right2)
}
1
// With octal escapes
var (
left  = []byte(&quot;\000\000&quot;)
right = []byte(&quot;\001\000&quot;)
)
// With hexa escapes
var (
left2  = []byte(&quot;\x00\x00&quot;)
right2 = []byte(&quot;\x01\x00&quot;)
)
func main() {
fmt.Println(left, right)
fmt.Println(left2, right2)
}
0&quot;) ) // With hexa escapes var ( left2 = []byte(&quot;\x00\x00&quot;) right2 = []byte(&quot;\x01\x00&quot;) ) 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:

https://stackoverflow.com/questions/38783260/go-explicit-array-initialization

https://stackoverflow.com/questions/36302441/keyed-items-in-golang-array-initialization

答案3

得分: 0

你不能在switch语句中使用[]byte,因为切片是不可比较的,而字符串是可比较的。所以看起来只需要使用以下代码:

const LEFT = `0000`
英文:

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

const LEFT = `0000`

huangapple
  • 本文由 发表于 2016年9月7日 02:31:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/39355642.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定