我正在玩围棋,但无法解决这个问题。这是我想做的一个人为的例子。基本上,我在 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)
}
关于将 interface{} 转换为数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40001715/