Hindley-Milner类型推断用于Hindley-Milner类型系统,它是System-F类型系统的限制。HM类型系统的有趣特征是它们具有参数多态性(又名泛型)。那是Golang拒绝拥有的最大的单一类型系统功能。
在这种令人沮丧的限制下,HM风格的类型推断是不可能的。让我们看一下未键入的代码:
func f(a) {
return a.method()
}
什么是f
?我们可能会注意到a
必须有一个方法,因此我们可以使用匿名接口:func f(a interface { method() ??? }) ???
。但是,我们不知道返回类型是什么。使用类型变量,我们可以将类型声明为
func f[T](a interface{ method() T }) T
但是,Go没有类型变量,因此这行不通。虽然隐式接口使类型推断的某些方面更加容易,但现在我们无法找出函数调用的返回类型。HM系统要求声明所有函数,而不是暗含所有函数,每个名称只能具有一个类型(而Go的方法在不同的接口中可以具有不同的类型)。
相反,Go要求始终始终对函数进行完全声明,但允许变量使用类型推断。这是可能的,因为分配的右侧variable := expression
在程序的那个位置已经具有已知的类型。这种类型推论是简单,正确和线性的。
- 在声明时立即知道变量的类型,而HM推理必须首先潜在地对整个程序进行类型检查。这也对错误消息的质量产生了显着影响。
- Go的类型推断方法将始终为变量选择最特定的类型,而HM选择最通用的类型。即使使用Go的隐式接口,这也可以清晰地处理子类型。