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