不能对类型参数使用类型断言

Cannot use type assertion on type parameter

我们不能对泛型变量使用类型断言。考虑到 interface{} 允许,但受 interface{} 约束的泛型,这似乎是非常奇怪的行为。想知道是否有任何解决方法?

// This works
func isInt(x interface{}) bool {
    _, ok := x.(int)
    return ok;
}

// Compile Error
// invalid operation: cannot use type assertion on type parameter 
// value x (variable of type T constrained by interface{})
func isInt2[T interface{}](x T) bool {
    _, ok := x.(int)
    return ok;
}

tl;博士

您只能对接口值执行类型断言。所以你必须先将 x 转换为有效的接口类型, any / interface{} 在这种情况下:

func isInt[T any](x T) (ok bool) {

    _, ok = any(x).(int) // convert, then assert
    return
}

那么为什么会这样 fail to compile

_, ok = x.(int)   // ... cannot use type assertion on type parameter value ...

更一般地说,x 的类型 T 是类型参数,而不是接口。它仅受接口约束。此外,Go(修订版 1.18)语言规范明确指出 type parameters are not allowed in a type assertion:

For an expression x of interface type, but not a type parameter, and a type T ... the notation x.(T) is called a type assertion.


也来自 generics tutorial 为什么需要在 compile-time 解析参数类型:

While a type parameter’s constraint typically represents a set of types, at compile time the type parameter stands for a single type – the type provided as a type argument by the calling code. If the type argument’s type isn’t allowed by the type parameter’s constraint, the code won’t compile.