Scala中的嵌套模式匹配

时间:2018-02-12 17:49:49

标签: scala pattern-matching matching

我是Scala的新手,我正在努力了解模式匹配的工作原理。所以我写了这个基本代码,它返回了预期的结果:

def test(choice: Int): String = choice match {
  case x if x > 0 && x%2 == 0 => "positive even number"
  case x if x > 0 && x%2 != 0 => "positive odd number"
  case 0 => "null"
  case x if x < 0 && x%2 == 0 => "negative even number" 
  case x if x < 0 && x%2 != 0 => "negative odd number"
}

现在我正在尝试做一些更精细的事情:

def test(choice: Int): String = choice match {

  case x if x%2 == 0 => x match {
    case y if y > 0 => "even and positive number" 
    case y if y < 0 => "even and negative number"
    }
  case 0 => "null"
  case x if x%2 != 0 => x match {
    case y if y > 0 => "odd and positive number" 
    case y if y < 0 => "odd and negative number"
    }
}

但它失败了。这是控制台上的错误消息:

scala> def test(choice: Int): String = choice match {
     |
     |   case x if x%2 == 0 => x match {
     | case y if y > 0 => "even and positive number"
     | Display all 600 possibilities? (y or n)
     [...]

     |  if y < 0 => "even and negative number"
<console>:5: error: '(' expected but identifier found.
 if y < 0 => "even and negative number"
    ^

    [...]

有人可以告诉我我做错了什么,并向我详细介绍了我对Scala的误解,特别是match方法。

2 个答案:

答案 0 :(得分:2)

它为我编译。案例的顺序与编译的成功无关(但是,case 0分支永远不会匹配,因为case x if x%2==0匹配x=0。您可能想要case 0分支第一个)

我认为您的问题是因为在终端中使用制表符而不是空格。

如果您在项目的文件中使用此代码,它也会编译。如果您希望它在控制台中工作,您可以:

  • 在粘贴代码之前将标签转换为空格
  • 使用:paste命令在REPL中输入粘贴模式,粘贴代码并使用Ctrl-D退出粘贴模式(或者REPL告诉您组合的任何内容 - 这是Mac上的那个)。 / LI>

答案 1 :(得分:0)

在您的第一个代码中,您在前两种情况下测试x> 0,然后测试0本身。

在第二个代码中,您不测试x> 0,但x%2 == 0已经匹配x = 0,并且不考虑第二个外部匹配。

如果你把显式0匹配放在最上面,它可能会起作用,但我没有找到第二个错误,只匹配我能找到的第一个错误。 :)