英文:
Define a []byte without hex.DecodeString
问题
我正在使用一个HID驱动程序,这个驱动程序会读取一个[]byte
缓冲区中的几个不同的报告。当我使用hex.EncodeToString(buffer)
时,它会返回一个类似于0000
、0100
或0200
的字符串。我想使用一个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
将十六进制的0000
或0100
转换为两个字节而不是四个字节:
"\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('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:
<!-- language: lang-golang -->
var LEFT []byte{1,0}
// or
var LEFT []byte("\x01\x00")
答案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("\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")
}
答案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("// 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)
}
0// 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)
}
0")
right = []byte("// 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)
}
1// 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)
}
0")
)
// 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:
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`
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论