Reflection 如何使基于反射的GO代码更简单?

Reflection 如何使基于反射的GO代码更简单?,reflection,go,Reflection,Go,我正在使用一个非常复杂的协议对一个相当复杂的结构进行编码,该协议是ASN和XDR的变体以及其他编码的混合 我基于github上提供的xdr编码器实现。代码是基于反射的,可以工作,但我不喜欢我实现目标类型开关的方式: st := ve.Type().String() switch st { case "time.Time": 我认为以下方法可能更好,但我无法使其正常工作: switch ve.(type) { case time.Time: 它不起作用的原因是ve具有相同的反射

我正在使用一个非常复杂的协议对一个相当复杂的结构进行编码,该协议是ASN和XDR的变体以及其他编码的混合

我基于github上提供的xdr编码器实现。代码是基于反射的,可以工作,但我不喜欢我实现目标类型开关的方式:

st := ve.Type().String()
    switch st {
    case "time.Time":
我认为以下方法可能更好,但我无法使其正常工作:

switch ve.(type) {
case time.Time:
它不起作用的原因是ve具有相同的反射类型,而不是目标类型

以下函数提供了代码的完整上下文:

func (enc *encoderState) encode(v reflect.Value) {

ve := enc.indirect(v)

st := ve.Type().String()
switch st {
case "time.Time":
    log.Println("Handling time.Time")
    t, ok := ve.Interface().(time.Time)
    if !ok {
        enc.err = errors.New("Failed to type assert to time.Time")
        return
    }
    enc.encodeTime(t)
    return
case "[]uint8":
    log.Println("Handling []uint8")
    enc.writeOctetString(ve.Bytes())
    return
default:
    log.Printf("Handling type: %v by kind: %v\n", st, ve.Kind())
}

// Handle native Go types.
switch ve.Kind() {
case reflect.Uint8: // , reflect.Int8
    enc.writeUint8(uint8(v.Uint()))
    return
case reflect.Uint16: // , reflect.Int16
    enc.writeUint16(uint16(v.Uint()))
    return
case reflect.Bool:
    enc.writeBool(ve.Bool())
    return
case reflect.Struct:
    enc.encodeStruct(ve)
    return
case reflect.Interface:
    enc.encodeInterface(ve)
    return
}

// The only unhandled types left are unsupported.  At the time of this
// writing the only remaining unsupported types that exist are
// reflect.Uintptr and reflect.UnsafePointer.
enc.err = errors.New(fmt.Sprintf("unsupported Go type '%s'", ve.Kind().String()))
}

如果你知道一个更好的例子,可以切换类型和种类更好,请让我知道

多谢各位

更新

阅读解决方案后,我调整到一个可行的变体:

vi := ve.Interface()
switch st := vi.(type) {
case time.Time:
    enc.encodeTime(vi.(time.Time))
    return
case []uint8:
    enc.writeOctetString(vi.([]byte))
    return
default:
    log.Printf("Handling type: %v by kind: %v\n", st, ve.Kind())
}
在以下页面上使用:

您还可以打开而不是字符串:

switch ve.Type() {
case reflect.TypeOf(time.Time{}):
    log.Println("Handling time.Time")
    ...
case reflect.TypeOf([]byte{}):
    log.Println("Handling []uint8")
    ...
case reflect.TypeOf(uint8(0)):
    ...
}
switch ve.Type() {
case reflect.TypeOf(time.Time{}):
    log.Println("Handling time.Time")
    ...
case reflect.TypeOf([]byte{}):
    log.Println("Handling []uint8")
    ...
case reflect.TypeOf(uint8(0)):
    ...
}