问题描述
我刚刚观看了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))
然后:
- 如果没有匹配类型,您将无法编写返回类型(您必须这样做,因为它是一个重载方法);
- 即使可以,也无法表达编译主体所需的约束“
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
将无法编译(如果编译了,您也无法编写其返回类型)。