-
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: support type inference on generic structs #61731
Comments
CC @griesemer This seems to be suggesting that we can use a composite literal with a generic type and infer the type arguments from the elements of the composite literal. Seems doable at first glance. It might make a generic We would need to consider all types of composite literals. For example, should this work for |
This would make generic types so much more ergonomic to work with. I can't count the number of times I've written a function like: func NewPair[L, R any](left L, right R) Pair[L, R] {
return Pair[L, R]{Left: left, Right: right}
} and thought to myself "surely at least one of those In addition, it would be great if this could be extended to type names in general, and not just literals. For instance, consider: type Pairer[L, R any] interface {
Left() L
Right() R
}
type PairerList[P Pairer[L, R], L, R any] []P
type myPair struct {
left int
right int64
}
func (mp myPair) Left() int { return mp.left }
func (mp myPair) Right() int64 { return mp.right }
var myList PairerList[myPairType, int, int64] It would be nice if that last declaration could instead be written as: var myList PairerList[myPairType] since the other type parameters can be unambiguously inferred from the return types of the methods on func NewPairList[P Pairer[L, R], L, R any](pairs ...P) PairerList[P, L, R] {
return pairs
} can be called as One situation where I've found myself wanting this particularly often is when trying to design APIs that rely on embedding: type MyNode struct {
NodeBase[SomeType]
} where you might want to add some constraints to what types are allowed as type parameters to the embedded type, but where adding those constraints would force the user to type out a bunch of additional type arguments every time, making for a very cumbersome API. |
#61731 (comment) focusing on
Also named types.
|
Presumably it could work the same as the following does today: func F[T any](a, b T) {}
func main() {
// mismatched types untyped int and
// untyped string (cannot infer T)
F(1, "3")
}
|
@timothy-king I think these are the only reasonable answers consistent with the rest of the language: []Pair{{1, 2}, {"3", 4}} // reject with incompatible types int and string
[]Pair{{1, 2}, {3.0, 4}} // []Pair[float64, int] - mix of float and integer constants default types to float64
type NamedInt int
[]Pair{{1, 2}, {NamedInt(3), 4} // []Pair[NamedInt, int] - each type parameter is independent |
I think this invariant is implicit in many of the replies but I'd like to make it explicit: inference on a composite literal must produce the same results as the equivalent function call inference. For example, with type Pair[K, V any] struct{/*...*/} and func MakePair[K, V any](K, V) Pair[K,V] {/*...*/} and fixed If we accept this, we can answer the question about what []Pair{{a, b}, {c, d}, {e, f}} by constructing an equivalent function: a function with the same number and kind of parameters: func O[K, V any](a K, b V, c K, d V, e K, f V) {} I believe this approach generalizes to any composite literal. |
Here's a runable answer to @timothy-king's questions using that principle: https://go.dev/play/p/czPc_jc-gYK |
(I couldn't find an existing issue for this, but if there is, feel free to close!)
Problem
There's some inconsistencies in the capabilities of type inference for generics.
With functions, type inference works beautifully:
Structs also work, but they require you to explicitly pass in the generic types:
It feels rather unfortunate that you need to explicitly set the
[*Input, Output]
when usage and even syntax is otherwise so similar.Proposal
Support type inference on structs, allowing the following:
When the concrete types in
indexJson
andindexHtml
don't line up, it's a type error.Thanks for your consideration!
The text was updated successfully, but these errors were encountered: