我有一个函数,它接收一个[]byte
,但是我手头有的是一个int
,如何最好地进行转换?
err = a.Write([]byte(myInt))
我想我可以走弯路,将其转换为字符串,并将其放入字节中,但这听起来很丑陋,我想有更好的方法来解决它。
我有一个函数,它接收一个[]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)
}
查看"encoding/binary"包。特别是Read和Write函数:
binary.Write(a, binary.LittleEndian, myInt)
binary.LittleEndian.PutUint64(bs, value)
比 int -> string -> byte 快得多。 - Kostub Deshmukhbinary.Write
返回的错误,参见@Agniva De Sarker的答案。不能直接使用int
类型,需要将其强制转换为int64
或类似类型。 - aleb抱歉,可能有些晚了。但我认为在Go文档中找到了更好的实现方式。
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哈希到字节的任何方法,但是我首先发现了用于此的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
然而,这种方法使用的是绝对值。 如果你再花费一个字节,就可以传输符号。
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
或者 new(https://play.golang.org/p/7ZAK4QL96FO)
(该包还提供了将数据填充到现有切片中的函数)
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]
BenchmarkBig-12 28348621 40.62 ns/op
BenchmarkBit-12 731601145 1.641 ns/op
package main
import (
"github.com/ymz-ncnk/musgo_int"
)
func main() {
var myInt int = 1234
// from int to []byte
buf := make([]byte, musgo_int.Int(myInt).SizeMUS())
musgo_int.Int(myInt).MarshalMUS(buf)
// from []byte to int
_, err := (*musgo_int.Int)(&myInt).UnmarshalMUS(buf)
if err != nil {
panic(err)
}
}
添加此选项以处理基本的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
message MyData {
int32 id = 1;
}
在定义协议格式中了解更多
// Write
out, err := proto.Marshal(mydata)
阅读编写消息了解更多信息
将整数转换为字节切片。
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()
}
func toBytes[T any](val T) []byte {
return unsafe.Slice((*byte)(unsafe.Pointer(&val)), unsafe.Sizeof(val))
}
func toLEBytes[T any](val T) []byte {
bytes := toBytes(val)
if runningOnBigEndian() {
slices.Reverse(bytes)
}
return bytes
}
runningOnBigEndian()
函数。首先阅读这个问题的答案:
有没有更好的方法来检查Go语言的字节序。