php editor Youzi will answer a common question for everyone: the reason why the type cannot be inferred from the generic parameters of the constructor. In PHP, type inference for generic parameters is achieved through the default value of the parameter. However, in a constructor, since the parameters are passed in before the object is created, the type of the parameters cannot be inferred from the object's instance. This results in the inability to infer the type of the generic parameter in the constructor, and the type needs to be manually specified to solve this problem.
I have some generic code in go where I have a "master" type with a generic parameter and many "slave" types that should share the same generic parameters. The code looks similar to this:
type Doer[T any] interface { ModifyA(*A[T]) } type B[T any] struct { } func NewB[T any]() *B[T] { return new(B[T]) } func (b *B[T]) ModifyA(a *A[T]) { // Do a thing } type A[T any] struct{} func NewA[T any]() A[T] { return A[T]{} } func (a *A[T]) Run(doers ...Doer[T]) { for _, doer := range doers { doer.ModifyA(a) } } func main() { a := new(A[int]) a.Run(NewB()) // error here }
Basically, the user should definet
ona
and thent
onb
should be the same. This type of code works in other languages that support generics, but in go I get acannot infer t
compile error at the commented line (see the go playground code here). It seems to me that the type parameter ona
is set toint
, so the type parameter onb
should also be set toint
. I could callnewb[int]()
instead, but that seems too verbose to me. Why does this happen?
This is a variation on "Why can't the compiler infer the type parameters based on how the return type is used?" Answer: Because as of go 1.20, this is not how type inference works.
Type inferenceApplies to:
If you check these rules one by one:
newb()
Is there a type parameter list? No. You didn't specify a type parameter when calling it.
Are there other known type parameters that can be used to infer other type parameters? No, you didn't provide any type parameters at all. Note that this case applies to function calls where you provide a partial number of type parameters, for example:
func foo[T any, U *T]() {}
In the above you can only providet
, for examplefloat64
, the compiler will construct the replacement map usingt -> float64
and then inferu -> *float64
Finally, is there a list of normal function parameters? no.newb
is empty.
That’s all. The compiler does not infer type parameters based on how the function's return type is used.
At the time of writing, relevant proposals under discussion are:
The above is the detailed content of Unable to infer types in generic parameters of function constructor. For more information, please follow other related articles on the PHP Chinese website!