2 回答

TA贡献1805条经验 获得超10个赞
您不能==在接口值上使用相等运算符。即使动态类型相同,如果它们具有不同值的字段,比较也可能返回 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

TA贡献1780条经验 获得超5个赞
这是使用 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
}
- 2 回答
- 0 关注
- 161 浏览
添加回答
举报