首页  >  文章  >  后端开发  >  无法推断函数构造函数的泛型参数中的类型

无法推断函数构造函数的泛型参数中的类型

PHPz
PHPz转载
2024-02-09 08:00:32640浏览

无法推断函数构造函数的泛型参数中的类型

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 开始,这不是类型推断的工作方式。

类型推断适用于:

  • 类型参数列表
  • 使用已知类型参数初始化的替换映射 m(如果有)
  • 普通函数参数的(可能为空)列表(仅在函数调用的情况下)

如果您一一检查这些规则:

  • newb() 有类型参数列表吗?不。您在调用它时没有指定类型参数。

  • 是否有其他已知的类型参数可以用来推断其他类型参数?不,您根本没有提供任何类型参数。请注意,这种情况适用于您提供部分数量的类型参数的函数调用,例如:

    func foo[T any, U *T]() {}

    在上面您只能提供 t,例如float64,编译器将使用 t -> float64 构造替换映射,然后推断 u -> *float64

  • 最后,有普通函数参数的列表吗?否。newb 为空。

仅此而已。编译器不会根据函数返回类型的使用方式推断类型参数。

在撰写本文时,正在讨论的相关提案有:

以上是无法推断函数构造函数的泛型参数中的类型的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:stackoverflow.com。如有侵权,请联系admin@php.cn删除