Home > Back-end >  Cannot use type assertion on value of type parameter type
Cannot use type assertion on value of type parameter type

Time:03-24

We can't use type assertions on generic typed variables. This seems like really strange behavior considering it's allowed by interface{}, but not by a generic constrained by interface{}. Wondering if there are any work arounds?

// 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;
}

CodePudding user response:

The language spec for type assertion, explicitly states type parameters are not allowed:

Type assertions

For an expression x of interface type, but not a type parameter, and a type T, the primary expression

x.(T)

... is called a type assertion.


Anyway, you don't need generics to achieve what you want.

What you had in your question is fine:

func isInt(x interface{}) (ok bool) {
    _, ok = x.(int)
    return
}

or on go 1.18 you can shorten interface{} to any:

func isInt(x any) (ok bool) {
    _, ok = x.(int)
    return
}

This example shows how a constraint type must have a core-type at compilation:

type Number interface {
    int64 | float64
}

// var n Number  // FAILS to compile
var n int64      // works

https://go.dev/play/p/ebDgmXvsz-X

from the generics tutorial:

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.

CodePudding user response:

This works.

func isInt[T interface{}](x T) bool {
    _, ok := interface{}(x).(int)
    return ok
}

Exmample on Go Playground: https://go.dev/play/p/n_-Rdtx50ip

  • Related