为什么匹配类型被添加到 scala3 尽管方法 uoverloading 履行相同的角色?

Why were match types added to scala3 despite method uoverloading fulfilling the same role?

我刚看了 rockthejvm 的视频,可以找到 here。我唯一的问题是它无法解决匹配类型是否可以做任何方法重载不能做的事情?匹配类型有什么比方法重载做得更好的吗?看起来它们只是方法重载的可扩展性较差的版本。

任何智慧将不胜感激。

此示例来自 the documentation

type LeafElem[X] = X match
  case String => Char
  case Array[t] => LeafElem[t]
  case Iterable[t] => LeafElem[t]
  case AnyVal => X

def leafElem[X](x: X): LeafElem[X] = x match
  case x: String      => x.charAt(0)
  case x: Array[t]    => leafElem(x(9))
  case x: Iterable[t] => leafElem(x.head)
  case x: AnyVal      => x

不能翻译成重载。非递归情况很简单:

def leafElem(x: String): Char = x.charAt(0)
def leafElem(x: AnyVal): AnyVal = x

但是你会用数组做什么?如果你写

def leafElem[T](x: Array[T]): ??? = leafElem(x(9))

然后:

  1. 没有匹配类型你不能写 return 类型(你必须这样做,因为它是一个重载方法);
  2. 即使可以,也不能表达主体编译所需的约束“T 必须是 leafElem 重载的参数类型”。

或者考虑这个非递归的例子

type Elem[X] = X match
  case String => Char
  case Array[t] => t
  case Iterable[t] => t

def elem[X](x: X): Elem[X] = x match { /* doesn't really matter */ }

您可以使用匹配类型编写

def mapElems[X](seq: Seq[X]): Seq[Elem[X]] = seq.map(elem(_))

如果您为不同的情况重载了 elem 方法,mapElems 将无法编译(如果可以的话,您也无法编写其 return 类型)。