如何简化switch语句

时间:2019-12-16 17:11:44

标签: go binary switch-statement byte reflect

我有一个解码器功能,该功能需要一个字节片和reflect.Kind并返回一个接口和一个错误。当在代码的其他部分中使用该接口时,将声明该接口。有没有一种方法可以简化我的switch语句,这样我就不必在每种情况下都重复NewReader,Read和错误处理?

我现在所拥有的:

func decoder(byteValue []byte, t reflect.Kind) (interface{}, error) {
    switch t {
    case reflect.Int16:
        var ret int16
        buf := bytes.NewReader(byteValue)
        err := binary.Read(buf, binary.BigEndian, &ret)
        if err != nil {
            return 0, err
        }
        return ret, nil
    case reflect.Int32:
        var ret int32
        buf := bytes.NewReader(byteValue)
        err := binary.Read(buf, binary.BigEndian, &ret)
        if err != nil {
            return 0, err
        }
        return ret, nil
    }
}

我在寻找什么

func decoder(byteValue []byte, t reflect.Kind) (interface{}, error) {
    switch t {
    case reflect.Int16:
        var ret int16
    case reflect.Int32:
        var ret int32
    }
    buf := bytes.NewReader(byteValue)
    err := binary.Read(buf, binary.BigEndian, &ret)
    if err != nil {
        return ret, err
    }
    return ret, nil
}

我知道这行不通,因为ret仅在开关盒的范围内定义,并在开关盒的范围外丢失。

1 个答案:

答案 0 :(得分:5)

确定:

var ret interface{}
switch t {
case reflect.Int16:
    var i int16
    ret = &i
case reflect.Int32:
    var i int32
    ret = &i
}
buf := bytes.NewReader(byteValue)
// NOT &ret since ret is already an interface value containing a pointer
err := binary.Read(buf, binary.BigEndian, ret)
if err != nil {
    return ret, err
}
return ret, nil

这始终是一个痛苦的解决方案,因为返回interface{}几乎没有用-调用者将总是必须进行断言或键入switch或反射。在这种情况下,我要做的是取值而不是reflect.Kind来填充-即binary.Read所做的事情:

func decoder(byteValue []byte, val interface{}) error {
    return binary.Read(bytes.NewReader(byteValue), binary.BigEndian, val)
}

当然,这不会为您节省很多重复的代码,这告诉您binary.Read已经是一个非常干净的API,实际上不需要包装。