让我思考的是为什么以下
<something> match { ... }
无法重写为
<something>.match({ ... }) # error: identifier expected but 'match' found.
我想这是因为将match
作为常规方法实现是不可能的,但我不确定。或许这是出于性能原因。
此外,既然宏已经可用,那么match
是否可以使用宏来实现? (不是应该这样做,而只是假设)
编辑:这似乎与例如What is scala's experimental virtual pattern matcher?;感谢@ om-nom-nom指出它。
答案 0 :(得分:2)
通过将其作为关键字,它不需要与Any类型相关联,因此编译器可以自由地推断(部分)函数的输入类型。如果它是Any的方法,则将函数[A,B]作为参数。
实际意义是
3 match { case "foo" => "bar" }
导致编译错误'类型不匹配'
但是a(type paramerterless)matchMethod;
3.matchMethod { case "foo" => "bar" }
导致运行时异常'scala.MatchError'
那么即使我们详细地明确地对这些类型进行了参数化,我们仍然不会因以下情况而出现编译错误:
"foo".matchMethod[Int, String] { case 3 => "bar" }
相反,我们会得到运行时异常'java.lang.ClassCastException',因为我们必须使用.asInstanceOf。
另一个好处是语法高亮,匹配跳出代码比另一种方法更多,我相信它应该得到,因为模式匹配是Scala的一个关键部分,值得特别关注。
附加:出于类似的原因,您希望try catch是一个关键字构造,而不是一个将两个函数作为参数的函数。匹配与catch一致,这也与Java一致。
这个答案是Martin Odersky的扩展,TravisBrown首先指出
答案 1 :(得分:2)
众所周知,函数式编程中的匹配可以在没有任何特殊语言特性的情况下完成(Church Encoding)
trait List[+T] {
def mmatch[R](nil: => R, cons: (T, List[T]) => R): R
}
object Nil extends List[Nothing] {
def mmatch[R](nil: => R, cons: (Nothing, List[Nothing]) => R) = nil
}
class Cons[+T](head: T, tail: List[T]) extends List[T] {
def mmatch[R](nil: => R, cons: (T, List[T]) => R) = cons(head, tail)
}
def sum(l: List[Int]): Int = l mmatch (
nil = 0,
cons = (x, xs) => x + sum(xs)
)
val list = new Cons(1, new Cons(2, Nil))
println(sum(list))
在此解释中,当你写
sealed trait List[+T]
case object Nil extends List[Nothing]
case class Cons[+T](head: T, tail: List[T]) extends List[T]
单词sealed
是提供match
函数的值/术语。
因此,阅读问题的一种方法是,为什么不这样做呢?为什么不用其他基本语言功能构建匹配而不是提供句法匹配?
原因是句法match
提供了一些人们喜欢的语法糖:
重叠匹配功能:
sealed trait A
sealed trait B
case object X extends A
case object Y extends A with B
case object Z extends B
嵌套匹配函数:
(1 :: 2 :: Nil) match {
case x :: y :: Nil => ???
}
在没有语法糖的情况下写这是非常尴尬的。你能行的;我在trying to implement monadic extractors时试图探索这种可能性。但肯定不那么漂亮。
自动选择开放与封闭匹配功能。
也就是说,Scala中的提取器就像开放匹配函数一样,因为任何函数都可能因返回None
而失败;编译器不会检查完整的match
,但您可以根据需要链接多个,Scala选择第一个。另一方面,sealed
特征提供闭合匹配函数,具有完整性检查的好处。这些需要由单独的函数提供,但Scala允许您对两者使用相同的match
语法。
就我个人而言,我怀疑上述要求最终不需要为比赛提供特殊的句法支持。我怀疑其他更通用的语言功能最终可以提供相同的好处,特别是在嵌套匹配方面。但是,目前使用特殊的match
语法直接解决问题更有意义。