-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
spec: can not use instantiated type in type switch, unless constraints are satisfied #64800
Comments
FWIW this isn't really a "bug", because it's working as specified. And I didn't want to file it as a proposal, because it obviously intersects with other proposals (like #45380) and I'm not sure this is something we'd want to do in any case. I just noticed it when trying to implement persistent data structures as interfaces and wanting to special case one implementation that only works with stricter constraints. And thought it might be interesting to keep this in mind as something we might want to allow at some point. |
I think it works as intended. By composition, it means that it should only work if the constraint interface in F is at least Perhaps that what you want is to be able to assert whether a type T is comparable and deal with being able to then call X[T]? |
Type-assertions are about inspecting the dynamic type of an interface. It is explicitly about making a runtime assertion that goes beyond what the static type guarantees. By analogy with your argument, I could say you shouldn't be able to write There is no reason why a type-parameter constrained on
That would be one way to enable this (I did mention the connection to #45380). But func F[T any](v any) {
switch type T {
case comparable:
_, ok := v.(X[T])
}
} is still a pretty awkward way to write this. But to be clear: I was explicitly not suggesting that we do anything concrete about this, in the near future. I'm not sure I think it's a good idea to allow this type-assertion. I just don't see a reason why we can't and it seems like a reasonable thing to want to do. |
It is type assertion related? Same error for the following code: func F[T any](v any) {
var _ X[T]
} |
I do think that's different. But I can see the point. I did not consider the fact that a type-assertion has to assign the zero value to its left-hand side as well and that zero value can not exist. So yes, I don't think this works after all. |
I'd agree for interfaces but here T is a type parameter. If the underlying implementation uses an interface type, it's not really one for various reasons. A more befitting analogy would be to be able to type assert non interface types. That would be checked at compile-time. A type constraint is about static guarantees.
You're probably getting confused which happens. On the other hand, a type parameter which satisfies Here that's not even sufficient because of composition. Imagine that T is a slice of int for instance. How could X[T] even exist?
That's an opinion but if that makes sense, it's not particularly awkward to me.
|
Maybe what OP needs is like: func F[T any](v any) {
switch T := T.(constraint) {
case comparable:
_, ok := v.(X[T])
println(ok)
}
} |
Go version
go version go1.21.4 linux/amd64
What operating system and processor architecture are you using (
go env
)?What did you do?
Playground
What did you expect to see?
The program compiling and running, outputting
true
,false
,false
.We can still meaningfully ask the question if the dynamic type of an interface is
X[T]
, even ifT
is not comparable. The answer would befalse
in that case, but that's fine.F
might be able to work with any type, but do something more efficient if it is anX[T]
.What did you see instead?
The text was updated successfully, but these errors were encountered: