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.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))}
}

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

最佳答案

看起来这两种类型都具有基础类型 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))
    }
}

然而,您在第一个示例中所做的事情并不少见。有时反射不会削减它。在这些情况下,我对您的类型转换有一些建议。而不是 switch md.(type)switch ea := md.(type)。这将允许您删除像 ea := md.(*amf0.EcmaArrayType) 这样的行。

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

关于types - go 中的类型转换问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13332746/

相关文章:

python 强/弱动态/静态类型语言?

go - 如何检测 TCPConn 是否存活

go - 结构片不能插入golang中的接口(interface)片

sorting - 堆索引示例说明

go - 使用 Go 中的 DELETE 端点

python - Python 中类型和对象的先有鸡还是先有蛋悖论

python - 对象属性和类型属性之间的区别

c# - 是否可以在枚举中保存类型(使用 "typeof()")?

c++ - 推断类型是否来自模板类的方法

go - 如何增加 klog 级别的冗长程度?