61

我有一个接收 a 的函数,[]byte但我拥有的是一个int,进行这种转换的最佳方法是什么?

err = a.Write([]byte(myInt))

我想我可以走很长的路,把它变成一个字符串,然后把它变成字节,但这听起来很难看,我想有更好的方法来做到这一点。

4

8 回答 8

65

我同意 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)
}
于 2013-06-03T02:38:32.910 回答
31

查看“编码/二进制”包。特别是读取写入功能:

binary.Write(a, binary.LittleEndian, myInt)
于 2013-06-02T23:56:44.583 回答
19

抱歉,这可能有点晚了。但我认为我在 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())
于 2014-09-30T07:16:34.997 回答
3

我认为 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

(该包还提供了填充现有切片的功能)

https://golang.org/pkg/math/big/#Int.FillBytes

于 2021-04-10T14:37:56.087 回答
1

添加此选项以处理基本 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

于 2020-11-05T08:37:39.753 回答
0

将整数转换为字节切片。

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()
}
于 2021-12-26T19:39:36.763 回答
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
  1. https://github.com/golang/go/blob/go1.16.5/src/encoding/gob/encode.go#L113-L117
于 2021-07-02T23:23:07.180 回答
-6

将其转换为字符串有什么问题?

[]byte(fmt.Sprintf("%d", myint))
于 2018-03-23T17:52:03.087 回答