我有一个接收[]byte
的函数,但我拥有的是int
,这个转换的最佳方式是什么?
err = a.Write([]byte(myInt))
我想我可以走很长的路,把它变成一个字符串然后把它放到字节中,但听起来很难看,我猜有更好的方法可以做到。
答案 0 :(得分:42)
我同意Brainstorm的方法:假设您传递的是机器友好的二进制表示,请使用encoding/binary
库。 OP表明binary.Write()
可能会有一些开销。查看the source实现Write()
,我发现它做了一些运行时决策以获得最大的灵活性。
189 func Write(w io.Writer, order ByteOrder, data interface{}) error {
190 // Fast path for basic types.
191 var b [8]byte
192 var bs []byte
193 switch v := data.(type) {
194 case *int8:
195 bs = b[:1]
196 b[0] = byte(*v)
197 case int8:
198 bs = b[:1]
199 b[0] = byte(v)
200 case *uint8:
201 bs = b[:1]
202 b[0] = *v
...
右? Write()接受一个非常通用的data
第三个参数,并且随着Go运行时强制进入编码类型信息,这会产生一些开销。由于Write()
在这里做了一些你根本不需要的运行时决策,也许你可以直接调用编码函数并查看它是否表现更好。
这样的事情:
package main
import (
"encoding/binary"
"fmt"
)
func main() {
bs := make([]byte, 4)
binary.LittleEndian.PutUint32(bs, 31415926)
fmt.Println(bs)
}
告诉我们这是如何表现的。
否则,如果您只是想获取整数的ASCII表示,则可以获取字符串表示(可能包含strconv.Itoa
)并将该字符串强制转换为[]byte
类型。
package main
import (
"fmt"
"strconv"
)
func main() {
bs := []byte(strconv.Itoa(31415926))
fmt.Println(bs)
}
答案 1 :(得分:24)
查看“encoding / binary”包。特别是读写功能:
binary.Write(a, binary.LittleEndian, myInt)
答案 2 :(得分:10)
对不起,这可能有点晚了。但我认为我在go docs上找到了更好的实现。
buf := new(bytes.Buffer)
var num uint16 = 1234
err := binary.Write(buf, binary.LittleEndian, num)
if err != nil {
fmt.Println("binary.Write failed:", err)
}
fmt.Printf("% x", buf.Bytes())
答案 3 :(得分:2)
我认为 int 类型有任何方法可以将 int 哈希转换为字节,但首先我找到了 math / big 方法 https://golang.org/pkg/math/big/
var f int = 52452356235; // int
var s = big.NewInt(int64(f)) // int to big Int
var b = s.Bytes() // big Int to bytes
// b - byte slise
var r = big.NewInt(0).SetBytes(b) // bytes to big Int
var i int = int(r.Int64()) // big Int to int
https://play.golang.org/p/VAKSGw8XNQq
但是,此方法使用绝对值。 如果多花1个字节,就可以转移符号
func IntToBytes(i int) []byte{
if i > 0 {
return append(big.NewInt(int64(i)).Bytes(), byte(1))
}
return append(big.NewInt(int64(i)).Bytes(), byte(0))
}
func BytesToInt(b []byte) int{
if b[len(b)-1]==0 {
return -int(big.NewInt(0).SetBytes(b[:len(b)-1]).Int64())
}
return int(big.NewInt(0).SetBytes(b[:len(b)-1]).Int64())
}
https://play.golang.org/p/mR5Sp5hu4jk
或新的(https://play.golang.org/p/7ZAK4QL96FO)
(该包还提供了填充现有切片的功能)
答案 4 :(得分:0)
添加此选项以处理基本的uint8到byte []转换
foo := 255 // 1 - 255
ufoo := uint16(foo)
far := []byte{0,0}
binary.LittleEndian.PutUint16(far, ufoo)
bar := int(far[0]) // back to int
fmt.Println("foo, far, bar : ",foo,far,bar)
输出:
foo, far, bar : 255 [255 0] 255
答案 5 :(得分:0)
这是另一种选择,基于 Go 源代码 [1]:
package main
import (
"encoding/binary"
"fmt"
"math/bits"
)
func encodeUint(x uint64) []byte {
buf := make([]byte, 8)
binary.BigEndian.PutUint64(buf, x)
return buf[bits.LeadingZeros64(x) >> 3:]
}
func main() {
for x := 0; x <= 64; x += 8 {
buf := encodeUint(1<<x-1)
fmt.Println(buf)
}
}
结果:
[]
[255]
[255 255]
[255 255 255]
[255 255 255 255]
[255 255 255 255 255]
[255 255 255 255 255 255]
[255 255 255 255 255 255 255]
[255 255 255 255 255 255 255 255]
比math/big
快得多:
BenchmarkBig-12 28348621 40.62 ns/op
BenchmarkBit-12 731601145 1.641 ns/op
答案 6 :(得分:-4)
将其转换为字符串有什么问题?
[]byte(fmt.Sprintf("%d", myint))