Types go中的类型转换问题

Types go中的类型转换问题,types,go,Types,Go,如何重写以下代码 switch md.(type) { case *amf0.EcmaArrayType: ea := md.(*amf0.EcmaArrayType) for k, v := range (*ea) { log.Printf("%v = %v\n", k, v) } if width == 0 {width = uint16((*ea)["width"].(amf0.NumberTy

如何重写以下代码

switch md.(type) {
    case *amf0.EcmaArrayType:
        ea := md.(*amf0.EcmaArrayType)
        for k, v := range (*ea) {
            log.Printf("%v = %v\n", k, v)
        }
        if width == 0 {width = uint16((*ea)["width"].(amf0.NumberType))}
        if height == 0 {height = uint16((*ea)["height"].(amf0.NumberType))}
    case *amf0.ObjectType:
        ea := md.(*amf0.ObjectType)
        for k, v := range (*ea) {
            log.Printf("%v = %v\n", k, v)
        }
        if width == 0 {width = uint16((*ea)["width"].(amf0.NumberType))}
        if height == 0 {height = uint16((*ea)["height"].(amf0.NumberType))}
}

对于不同的类型,它有两个完全重复的块。如果我在开关状态上方声明了
var ea interface{}
,由于编译错误,我无法调用
range(*ea)

在调用范围之前使用类型转换,例如

     range ((* your_desired_type)(*ea))

将所需类型替换为实际类型进行类型转换。

在调用范围之前使用类型转换,例如

     range ((* your_desired_type)(*ea))

您所需的\u类型
替换为用于类型转换的实际类型。

这两种类型似乎都具有基础类型
映射[string]something
,其中“something”的具体类型为
amf0.NumberType
。您执行的每个操作都可以使用反射进行模拟

switch md.(type) {
case *amf0.EcmaArrayType, *amf0.ObjectType:
    m := reflect.Indirect(reflect.ValueOf(md))
    for _, key := range m.MapKeys() {
        k, v := key.Interface(), m.MapIndex(key).Interface()
        log.Printf("%v = %v\n", k, v)
    }

    if width == 0 {
        w := m.MapIndex(reflect.ValueOf("width"))
        width = uint16(w.Interface().(amf0.NumberType))
    }

    if height == 0 {
        h := m.MapIndex(reflect.ValueOf("height"))
        height = uint16(h.Interface().(amf0.NumberType))
    }
}
然而,您在第一个示例中所做的事情并不少见。有些时候,反射不会切断它。在这种情况下,我对你的类型转换有一些建议。代替
开关md.(类型)
do
开关ea:=md.(类型)
。这将允许您删除像
ea:=md.(*amf0.EcmaArrayType)
这样的行


干代码更适合使用。它使更改更快,更不容易出现错误。然而,当所有重复的代码都在一个地方(比如类型开关)时,出现bug的可能性很小。进行更改仍然需要更长的时间,但这并不像整个项目中重复的代码那么糟糕。不要像其他重复代码一样担心严重重复的类型切换。

看起来这两种类型都有底层类型
map[string]something
,其中“something”有一个具体类型
amf0.NumberType
。您执行的每个操作都可以使用反射进行模拟

switch md.(type) {
case *amf0.EcmaArrayType, *amf0.ObjectType:
    m := reflect.Indirect(reflect.ValueOf(md))
    for _, key := range m.MapKeys() {
        k, v := key.Interface(), m.MapIndex(key).Interface()
        log.Printf("%v = %v\n", k, v)
    }

    if width == 0 {
        w := m.MapIndex(reflect.ValueOf("width"))
        width = uint16(w.Interface().(amf0.NumberType))
    }

    if height == 0 {
        h := m.MapIndex(reflect.ValueOf("height"))
        height = uint16(h.Interface().(amf0.NumberType))
    }
}
然而,您在第一个示例中所做的事情并不少见。有些时候,反射不会切断它。在这种情况下,我对你的类型转换有一些建议。代替
开关md.(类型)
do
开关ea:=md.(类型)
。这将允许您删除像
ea:=md.(*amf0.EcmaArrayType)
这样的行


干代码更适合使用。它使更改更快,更不容易出现错误。然而,当所有重复的代码都在一个地方(比如类型开关)时,出现bug的可能性很小。进行更改仍然需要更长的时间,但这并不像整个项目中重复的代码那么糟糕。不要像担心其他重复代码一样担心大量重复的类型开关。

在这种特定情况下,我可能只会向未来的维护人员添加注释,指出重复的代码,或者按照如下方式删除它。(游乐场:)


您原始版本中的重复代码只是重复的源代码;因为它处理不同的类型,所以编译的代码是不同的。幸运的是,ObjectType案例的编译代码可以通过简单的类型转换ea=(*ObjectType)(et)轻松处理EcmaArrayType案例。

在这个特定的案例中,我可能只是向未来的维护人员添加注释,指出重复的代码,或者按照如下方式删除它。(游乐场:)


您原始版本中的重复代码只是重复的源代码;因为它处理不同的类型,所以编译的代码是不同的。幸运的是,ObjectType案例的编译代码可以通过简单的类型转换ea=(*ObjectType)(et)轻松处理EcmaArrayType案例。

请在问题中发布相关代码,而不是链接到外部站点。根据一般经验,任何给定的问题或答案都应自行完成,仅使用链接作为参考。请在问题中发布相关代码,而不是链接到外部网站。作为一般的经验法则,任何给定的问题或答案都应该自己完成,只使用链接作为支持它的引用。以下代码未编译:var ea interface{}switch md.(type){case*amf0.EcmaArrayType:ea=md.(*amf0.EcmaArrayType)case*amf0.ObjectType:ea=md.(*amf0.ObjectType)}对于k,v:=range((*map[string]interface{})(*ea)){…}以下代码未编译:var-ea接口{}开关md.(type){case*amf0.ecmaarray类型:ea=md.(*amf0.ecmaarray类型)case*amf0.ObjectType:ea=md.(*amf0.ObjectType)}对于k,v:=range(*map[string]interface{})(*ea)){...}