我在玩围棋,但无法弄清楚。这是我想要做的一个人为的例子。基本上,我将数字保存在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

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

10-12 00:21
查看更多