如何检查切片界面元素是否具有相同的动态类型?

我有以下结构,它们遵循这个结构:


A是接口,B, C,D都是带接口的类型A。


我有一部分变量args都带有 interface 类型A,每个变量都可以是B, C,D特定类型。


我想写一个for循环来判断切片中的所有变量是否都属于同一个动态类型。


我写了以下代码:


var existingTyp A

for i, d := range args {

 switch typ := d.(type) {

   case *B, *C, *D:

    if existingTyp == nil {

        existingTyp = typ

    } else {

        if typ != existingTyp {

            panic("error!")

        }

   }

}

如何修改代码来实现我想要的?


翻过高山走不出你
浏览 162回答 2
2回答

holdtom

您不能==在接口值上使用相等运算符。即使动态类型相同,如果它们具有不同值的字段,比较也可能返回 false。或者它会恐慌 if B,C并且D与开始时不可比较。相反,您可以使用反射并使用==on reflect.Type。如果您添加更多实现A.func dynamicTypesEq(args []A) bool {    var a reflect.Type    for _, d := range args {        t := reflect.TypeOf(d)        if a == nil {            a = t            continue        }        if a != t {            return false        }    }    return true}使用一些示例切片调用函数:func main() {    a := []A{&B{}, &B{}, &B{}}    fmt.Println(dynamicTypesEq(a)) // true    b := []A{&C{}, &B{}, &B{}}    fmt.Println(dynamicTypesEq(b)) // false    c := []A{&D{}, &D{}, &B{}}    fmt.Println(dynamicTypesEq(c)) // false}请注意,如果输入具有*B和,则此函数报告错误B。显然,指针类型与基类型不同。游乐场:https ://go.dev/play/p/QOCvSyxGPRU

翻阅古今

这是使用 reflect 包的方法。如果某个元素的类型与第一个元素的类型不同,则切片包含混合值类型。func check(args []interface{}) bool {    if len(args) == 0 {        return true    }    t := reflect.TypeOf(args[0])    for _, v := range args[1:] {        if reflect.TypeOf(v) != t {            return false        }    }    return true}以下是如何在没有反射的情况下做到这一点。保留一个状态变量,记录最后看到的类型。如果当前类型不是最后一个类型,则切片包含混合值类型。func check(args []interface{}) bool {    const (        initState = iota        typeB        typeC        typeD    )    state := initState    for _, d := range args {        switch d.(type) {        case *B:            if state != initState && state != typeB {                return false            }            state = typeB        case *C:            if state != initState && state != typeC {                return false            }            state = typeC        case *D:            if state != initState && state != typeD {                return false            }            state = typeD        default:            panic("unsupported type")        }    }    return true}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go