我有一个接收 a 的函数,[]byte
但我拥有的是一个int
,进行这种转换的最佳方法是什么?
err = a.Write([]byte(myInt))
我想我可以走很长的路,把它变成一个字符串,然后把它变成字节,但这听起来很难看,我想有更好的方法来做到这一点。
我有一个接收 a 的函数,[]byte
但我拥有的是一个int
,进行这种转换的最佳方法是什么?
err = a.Write([]byte(myInt))
我想我可以走很长的路,把它变成一个字符串,然后把它变成字节,但这听起来很难看,我想有更好的方法来做到这一点。
我同意 Brainstorm 的方法:假设您传递的是机器友好的二进制表示,请使用该encoding/binary
库。OP 建议这binary.Write()
可能会有一些开销。查看实现的源代码Write()
,我发现它做了一些运行时决策以获得最大的灵活性。
func Write(w io.Writer, order ByteOrder, data interface{}) error {
// Fast path for basic types.
var b [8]byte
var bs []byte
switch v := data.(type) {
case *int8:
bs = b[:1]
b[0] = byte(*v)
case int8:
bs = b[:1]
b[0] = byte(v)
case *uint8:
bs = b[:1]
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)
}
抱歉,这可能有点晚了。但我认为我在 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())
我认为 int 类型有任何方法可以将 int 哈希转换为字节,但首先我找到了这个 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)
(该包还提供了填充现有切片的功能)
添加此选项以处理基本 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
将整数转换为字节切片。
import (
"bytes"
"encoding/binary"
"log"
)
func IntToBytes(num int64) []byte {
buff := new(bytes.Buffer)
bigOrLittleEndian := binary.BigEndian
err := binary.Write(buff, bigOrLittleEndian, num)
if err != nil {
log.Panic(err)
}
return buff.Bytes()
}
这是另一个选项,基于 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
将其转换为字符串有什么问题?
[]byte(fmt.Sprintf("%d", myint))