php小编柚子将为大家解答一个常见的问题:在构造函数的泛型参数中,无法推断出类型的原因。在PHP中,泛型参数的类型推断是通过参数的默认值来实现的。然而,在构造函数中,由于参数是在对象创建之前就被传入的,因此无法通过对象的实例来推断参数的类型。这就导致了构造函数中无法推断出泛型参数的类型,需要手动指定类型来解决这个问题。
我在 go 中有一些通用代码,其中有一个具有通用参数的“主”类型和许多应该共享相同通用参数的“从”类型。代码看起来与此类似:
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 }
基本上,用户应该在 a
上定义 t
,然后 b
上的 t
应该是相同的。此类代码可以在支持泛型的其他语言中工作,但在 go 中,我在注释行处收到 cannot infer t
编译错误(请参阅此处的 go playground 代码)。在我看来, a
上的类型参数设置为 int
,因此 b
上的类型参数也应设置为 int
。我可以改为调用 newb[int]()
,但这对我来说似乎过于冗长。为什么会出现这种情况?
这是“为什么编译器不能根据返回类型的使用方式推断类型参数?”的变体。答案:因为从 go 1.20 开始,这不是类型推断的工作方式。
类型推断适用于:
如果您一一检查这些规则:
newb()
有类型参数列表吗?不。您在调用它时没有指定类型参数。
是否有其他已知的类型参数可以用来推断其他类型参数?不,您根本没有提供任何类型参数。请注意,这种情况适用于您提供部分数量的类型参数的函数调用,例如:
func foo[T any, U *T]() {}
在上面您只能提供 t
,例如float64
,编译器将使用 t -> float64
构造替换映射,然后推断 u -> *float64
最后,有普通函数参数的列表吗?否。newb
为空。
仅此而已。编译器不会根据函数返回类型的使用方式推断类型参数。
在撰写本文时,正在讨论的相关提案有:
以上是无法推断函数构造函数的泛型参数中的类型的详细内容。更多信息请关注PHP中文网其他相关文章!