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