【发布时间】:2011-02-01 03:39:42
【问题描述】:
我正在自学 Scala,我有一个哲学问题。模式匹配是 Scala 的 语言 特性,还是仅仅是库特性?换句话说,如果我足够熟练,我是否可以编写xmatch,一个除了名称之外在其他方面都与match 相同的函数?实际上,我认为这是两个略有不同的问题:匹配库功能,可以是库功能吗?
我正在考虑尝试重写 match,纯粹是作为一种练习,但我想确保它是可能的。
【问题讨论】:
我正在自学 Scala,我有一个哲学问题。模式匹配是 Scala 的 语言 特性,还是仅仅是库特性?换句话说,如果我足够熟练,我是否可以编写xmatch,一个除了名称之外在其他方面都与match 相同的函数?实际上,我认为这是两个略有不同的问题:匹配库功能,可以是库功能吗?
我正在考虑尝试重写 match,纯粹是作为一种练习,但我想确保它是可能的。
【问题讨论】:
模式匹配是一种语言特性,其中match 语句只是最显着的例子。下面是另外两个常用的例子:
val List(x,y,(z: Int,w: Int)) = List("one","two",(3,4))
for ((text,i) <- List(("one",1),("two",2))) println(text + " = " + i)
所以,不,你不能自己做。该语言不允许您定义创建变量的新方法,因此这些事情只能在语言支持的情况下发生。
match 语句本身使用语言内部的模式匹配变量创建支持,但原则上可以作为库功能实现。但是,在某些情况下效率会很低:
// This is implemented with fast jumps, not slow if-then-else!
n match {
case 0 => // Do action 0
case 1 => // Do action 1
case 2 => // Do action 2
case _ => // Do default action
}
// This is tail recursive, so you won't overflow the stack!
def recursiveMatch(xs: List[Any]): List[Any] = xs match {
case (x @ Int) :: rest => recursiveMatch(rest)
case _ => xs
}
所以,总而言之,不,你不能自己编写模式匹配,虽然你可以编写 match 语句,但使用现有的语句是有优势的。
【讨论】:
实际上,match 曾经在库中实现,我听说过。 Scala 参考中的更改日志表明 match 在 2.0 版中成为保留关键字,此时 object.match { ... } 也不再是有效语法。
原则上比较容易实现:
implicit def toMyMatch[T](obj: T) = new {
def myMatch[R](f: T => R) = f(obj)
}
我不知道它停止以这种方式实施的确切原因。
【讨论】:
match 作为方法会阻止对部分函数内部进行的尾调用进行尾调用优化。
f 必须是一个部分函数。我会将上面的 sn-p 更改为 def myMatch[R](f: PartialFunction[T, R]) = f(obj)
match 实现为一个库,但不是case,这才是真正的魔法发生的地方
模式匹配绝对是一种语言特性。也就是说,因为在 Scala 中编写控制流结构非常容易(并且模式匹配很健壮),所以您可以轻松编写自己的 match(与其他语言相比)。
另一方面,match 仍然是语言核心的一部分(我认为),但它的行为更像是库中的东西。由于模式匹配的强大功能,感觉如此有机。
也就是说,是的,你绝对可以重写match。
【讨论】: