如何简化switch语句

问题描述 投票:0回答:1

我有一个解码器功能,该功能需要一个字节片和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仅在开关盒的范围内定义,并且在开关盒的范围之外丢失。

go binary switch-statement byte reflect
1个回答
4
投票

确定:

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{}几乎没有用-调用者将总是必须进行断言,类型切换或反射。在这种情况下,我要做的是使用要填充的值而不是reflect.Kind-即binary.Read的作用:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.