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