在Scala的部分函数中,“case”究竟是如何工作的?

时间:2013-11-24 06:09:01

标签: scala pattern-matching partialfunction

我刚刚开始使用Scala看似陡峭的学习曲线,并且无法完全理解“case”在部分函数中是如何工作的。

我查看了PartialFunction本身的定义,在那里我看到了如下示例:

val isEven: PartialFunction[Int, String] = { 
   case x if x % 2 == 0 => x+" is even" 
}

我遇到的部分是案例x,如果x%2 - Scala如何知道这是什么?这个“case”语句/关键字的正式定义是什么?

我认为我混淆的一个原因是因为在Lift中我看到如下内容(在Actor类中):

override def messageHandler = {
   case SomeKindOfUserMessageClass(id1, param1) => ....
   case AnotherKindOfUserMessageClass(id2) => ....
}

我直觉地理解这里发生了什么,但是我无法对如何使用“案例”进行某种统一的定义。对我来说更令人费解的是Scala编译器如何解开所有这些问题。

4 个答案:

答案 0 :(得分:8)

你问的问题是pattern matching。模式匹配块可以与match关键字一起使用,也可以用于定义函数或部分函数,​​具体取决于上下文。

您的第二个示例使用extractors。 Scala对m match { case A(x) => }的评估涉及调用A.unapply(m)case class的伴随对象是一个提取器(使用case类比实际编写unapply方法更常见)。

Scala Language Specification是一个艰难的阅读,但有时候值得一试,特别是如果你正在寻找形式主义。第8章是关于模式匹配。 8.4节介绍了在第一个例子中的case子句中使用if的想法。

答案 1 :(得分:5)

在" Case sequences as partial functions"在页面http://www.artima.com/pins1ed/case-classes-and-pattern-matching.html中,我发现了以下句子,我认为这些句子也可能是一个很好的答案。" case' case'应该使用"同样。

A sequence of cases (i.e., alternatives) in curly braces can be used anywhere a function literal can be used. Essentially, a case sequence is a function literal, only more general.案例序列没有单个入口点和参数列表,而是有多个入口点,每个入口点都有自己的参数列表。 Each case is an entry point to the function, and the parameters are specified with the pattern. The body of each entry point is the right-hand side of the case.

答案 2 :(得分:1)

认为case喜欢匹配某些条件或更具体的某种模式。您可以通过多种方式指定模式。

case SomeKindOfUserMessageClass(id1, param1):这表示该值应为SomeKindOfUserMessageClass类型,如果是,则将值解析为id1param1。所以它就像一个模式匹配的条件。

case x if x % 2 == 0:这表示条件是值应该可以被2整除,如果是,则将值绑定到x或者你可以说,将值绑定到x并且检查它是否可被2整除。

答案 3 :(得分:1)

把它想象成其他语言的switch语句。

在PHP中,您在每个选项之前使用单词case。在ruby中,你会使用“when”这个词......和其他语言中的相似。

它从上到下运行并运行匹配的第一个模式的代码。您可以根据值,类型,构造函数等进行匹配...它只运行一个代码块...并从上到下进行检查。

它可以是语法......

val x = List(1,2,3,4)
x match {
  case Nil => Nil
  case x => x map someFunction
}

或者您也可以在lambda表达式中使用模式匹配。

在coursera.org上查看scala中的课程函数式编程原理。如果你接受了这个,你就会在scala中有一个好头。。