首页 > 解决方案 > 尽管方法 uoverloading 起到了相同的作用,但为什么将匹配类型添加到 scala3 中?

问题描述

我只是在观看 rockthejvm 的视频,可以在此处找到。我唯一的问题是,如果匹配类型可以做任何方法重载不能做的事情,它无法解决?有什么比方法重载更好的匹配类型吗?似乎它们只是方法重载的扩展性较差的版本。

任何智慧将不胜感激。

标签: scalascala-3match-types

解决方案


文档中的这个例子:

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. 如果没有匹配类型,您将无法编写返回类型(您必须这样做,因为它是一个重载方法);
  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不会编译(如果确实如此,您也无法编写其返回类型)。


推荐阅读