-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: spec: permit using var.(type) when instantiating a generic function #58608
Comments
This seems like an extension of #34515 to add support for explicit generic instantiations, too. |
CC @griesemer Can you give an example where this would be useful? Thanks. |
Sometimes this feature provides a convenience that we don't need to import the package in which the value type is declared. |
Another benefit is that this feature will generalize the |
It would help with the irregularity some, but a type switch with a variable would still be irregular. A regular switch with a variable looks like switch v := f(); v {
// ...
} while a type switch with a variable looks like switch v := i.(type) {
// ...
} |
switch v := i.(type) {
// ...
} may be viewed as a short-from of switch v, T := i.(type); T {
// ...
} |
Would this only be allowed if
|
I can imagine this is theoretically useful when you want to instantiate Can you provide a realistic example? |
My experience with type switches and type assertions lead me to assume that the I'd worry about making it ambiguous whether I'd prefer to see a different syntax for writing "the static type of this value", so that it's clear how future language features might support both static and dynamic types in the same position, and so that a reader can clearly see which of the two a particular expression is referring to without having detailed knowledge of the language specification. However, I must admit I don't have a specific proposal for that; so far I can't think of any other situation where it's been necessary to express "the static type of this value", so I can't find precedent to copy. |
A couple of possibly useful situations off the top of my head: type Example struct { m map[int]string }
var ex Example
ex.m = make(ex.m.(type))
var ex2 ex.(type) // Might be stretching it a bit.
func F[T any]() T { ... }
v = F[v.(type)]() // 'twould be nice if this was automatic, to be honest. That first one has its own proposal already, #34515. Also worth noting that the last one won't help in situations where the result is being returned, despite the type having been declared elsewhere already. |
I agree with @apparentlymart that the syntax type Demo interface { M() }
type MyM struct{}
func (MyM) M() {}
func UseFunc[T any]() {}
var value = M(MyM)
UseFunc[value.(type)]() Here What this proposal is after is more like the |
yes, x is a static type. only static types are allowed |
It only needs to be consistent with the quality of reflection.TypeOf () But the return MyM type is not a reflect.Type. |
How about using [edit]: They only have different meaning when [edit 2]: Or, in |
Actually, by analogy with assertions and conversions, how about |
It creates parsing ambiguity. A statement that starts with |
It could be avoided by always assuming |
Part of my reservation about lightly-overloading the This One specific concrete decision to make, though, is that I think this I suppose though that it would be possible in principle to still express the non-declaration form by placing |
It should only be a problem in situations where it's ambiguous if it's an expression or a statement. It's notable that regardless of that ambiguity, type(v) on its own line would be a compile-time error anyways because it would be an unused expression that isn't a function call, though, interestingly, it would be one that's entirely a compile-time directive and produces no actual run-time code. That's why the method expression syntax is a problem: It allows you to both use it in an expression context and call a function. It might actually be less of a problem than it seems, though. I don't know how possible it would be for the parser to see |
As Ian said, this is a compile-type typeof like C's typeof, which we shouldn't use x.(type) syntax for, since that's a dynamic type. That aside, it's unclear that we should add typeof(V) to the language. For this specific use case, instead of writing
you can always write
And 99% of the time UseFunc is going to take the value already - generic functions that don't use the types in the argument list are rare - so you won't need that wrapper in the first place. |
Based on the discussion above, this proposal seems like a likely decline. |
No change in consensus, so declined. |
build error: invalid AST: use of .(type) outside type switch.
Hope to support value.(type) in generics code.
The text was updated successfully, but these errors were encountered: