将 interface{} 转换为数字

标签 go

我正在玩围棋,但无法解决这个问题。这是我想做的一个人为的例子。基本上,我在 interface{} 数据类型中保存了数字,我想编写用户指定大小的数字的二进制表示。

func main() {
   buf := new(bytes.Buffer)  // imported from encoding.binary 
   var val1 uint64 = 0xff    // 8 bytes
   var val2 float32 = 9.876  // 4 bytes

   var a interface{} = val1
   var b interface{} = val2

   // for argument sake, lets assume we want to write a as a uint8
   // to our binary file
   foo(buf.Bytes(), a, 1)

   // let's write b as a float64 to our binary file
   foo(buf,Bytes(), b, 8)

   // write buffer to file
   ...
}

// write the number in binary to the buffer
var foo (buf *bytes.Buffer, num interface{}, sizeInBytes int) {

   // TODO: somehow i need to convert num to the correct datatype
   //       let's assume the first scenario where num is unit64 and
   //       i need to make it uint8
   var tmp uint8 = num.(uint8) // error interface is uint64, not uint8
   var tmp uint8 = uint8(num)  // error (type interface {}) to type uint8: need type assertion

   // help please ^^^^^^ i assume writing a float32 as a float64 would
   // follow the same paradigm

    binary.Write(buf, binary.LittleEndian, num)
}

最佳答案

无论如何,您都需要为每个值断言一个具体类型,以便对其进行数字操作。由于转换较小的整数类型只是截断,您可以将所有整数值编码为 uint64 以减少您需要处理的情况的数量,然后以所需的位数切割 slice 。

func foo(buf *bytes.Buffer, num interface{}, sizeInBytes int) {
    switch sizeInBytes {
    case 1, 2, 4, 8:
        // OK
    default:
        panic("invalid size")
    }

    b := make([]byte, 8)
    var un uint64

    switch n := num.(type) {
    case float32:
        switch sizeInBytes {
        case 4:
            un = uint64(math.Float32bits(n))
        case 8:
            un = math.Float64bits(float64(n))
        default:
            panic("can't do that")
        }

    case float64:
        switch sizeInBytes {
        case 4:
            un = uint64(math.Float32bits(float32(n)))
        case 8:
            un = math.Float64bits(n)
        default:
            panic("can't do that")
        }
    case int8:
        un = uint64(n)
    case uint8:
        un = uint64(n)
    case uint16:
        un = uint64(n)
    case int16:
        un = uint64(n)
    case uint32:
        un = uint64(n)
    case int32:
        un = uint64(n)
    case uint64:
        un = uint64(n)
    case int64:
        un = uint64(n)
    case int:
        un = uint64(n)
    }

    binary.LittleEndian.PutUint64(b, un)
    b = b[:sizeInBytes]
    buf.Write(b)
}

https://play.golang.org/p/g6d5Bt1esI

关于将 interface{} 转换为数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40001715/

相关文章:

python - Python 和 Ruby 中用于 Web 编程的协程或延续。为什么不?

go - 在 go 中轮询函数直到 ok != true 的惯用方式

go - "A Tour of Go"想表达什么?

sockets - App Engine 开发服务器 - 套接字协议(protocol)类型错误

go - 为所有用户设置转到路径时出错。

go - 有没有一种方法可以在 Go 中生成类似于 Python 的 `secrets` 模块的加密强随机数?

go - 如何使用wasm中的<>运算符评估js值?

json - 解码 JSON 保留所有 key

Javascript fetch() 不止一次 ping 我的 golang 休息端点?

go - 没有 fmt.Print() 就不会发生光标移动