Scala模式匹配大小写被跳过

| 感谢您的出色示例,我尝试了一下,它可以按预期工作。很高兴看到有人了解问题的本质。但是,我认为我应该在使用Lift框架时使用Lift标记问题,因此(仍然)仍在发生此问题(尽管我仍然认为这可能与scala中的提取有关)。由于我不想在这里重现整个Lift设置,因为这会太多代码,所以我希望熟悉Lift的人可以理解我在这里所做的事情。我已经删除了更多变量,因此(对于某些人来说)更容易发现问题:
lazy val dispatch: LiftRules.DispatchPF = {
  // Explicitly setting guard to false to trigger the scenario
  case req: Req if false => () => println(\"shouldn\'t match\"); Empty
  // This should match since previous case will never match
  case Req(_, _, _) => () => println(\"should match\"); Empty
  // This is actually called...
  case _ => () => println(\"shouldn\'t reach here\"); Empty
}
和以前一样,如果我注释掉第一种情况,则第二种情况符合预期。 对于那些感兴趣的人,一个简单的解决方法是:
lazy val dispatch: LiftRules.DispatchPF = {
  case req: Req => {
    if (false) { // Obviously you put something more useful than false here...
      () => println(\"shouldn\'t match\"); Empty
    } else req match {
      // This matches
      case Req(_, _, _) => () => println(\"should match\"); Empty
      // This is now never called
      case other => () => println(\"shouldn\'t reach here\"); Empty
    }
  }
}
原始帖子 我是Scala的新手,所以我在这里可能做错了什么,但是我有一个模式匹配表达式,似乎已被跳过。这是代码:
lazy val dispatch: LiftRules.DispatchPF = {
   // Explicitly setting guard to false to trigger the scenario
   case req: Req if false => () => Full(...)
   // This should match since previous case will never match
   case Req(\"api\" :: \"test\" :: Nil, suffix, GetRequest) => () => Full(...)
   // This is actually called...
   case _ => () => println(\"not sure what\'s going on\"); Empty
}
如果我取出第一个
case
表达式,一切都会按预期进行。我倾向于认为这是一个错误(https://issues.scala-lang.org/browse/SI-2337),但是有人知道解决方法吗?     
已邀请:
        这确实是您在Scala错误跟踪器中引用的错误。
Req
是带有附带提取器方法的非大小写类,因此该错误将在此处显示。您介绍的解决方法似乎很好。 对于那些感兴趣的人,这里是一个示例示例,其中的错误得以显现:
class Sample(val a: String)

object Sample {
    def apply(a: String) = new Sample(a)
    def unapply(s: Sample) = Option(s.a)
}

val s = new Sample(\"a\")

val r = s match {
    case n: Sample if false => \"Wrong 1: \" + n
    case Sample(_) => \"Yay\" 
    case n => \"Wrong 2: \" + n
}

println(\"Found \" + r)
assert(r == \"Yay\")
    
        至少更改最后一行:
case other => () => { println(\"not sure what\'s going on \" + other); Empty }
告诉我们它打印什么     
        我只是输入了一个示例,该示例似乎与您的代码中的场景相同,并且可以在Scala 2.9中按预期工作:
case class Foo(x:String)
val bar = Foo(\"bar\")
bar match {
    case x:Foo if false => println(\"Impossible\")
    case Foo(x) => println(\"Expected: \" + x)
    case _ => println(\"Should not happen\")
}
输出outputs8ѭ 看看您是否可以在这样的独立示例中重现该错误,也许我们(或者如果是错误,Scala Dev Team可以找出问题所在:) 注意:好像我是第一次误读您的问题,对此感到抱歉。无论如何,我不会删除此部分,因为它可能对其他人有帮助。 使用模式匹配时,将执行第一个匹配的case语句,然后,匹配完成,所有其他case语句将被忽略! 您的问题是,第一个语句
case req:Req =>
匹配
Req
的每个实例。在匹配第一条语句并执行其代码之后,Scala会跳出匹配表达式,因为它已完成。第二个case语句可以匹配,但是对于任何给定的
Req
实例都不会执行,因为第一个匹配。据我所知,这被称为“ 12”个案例陈述。 因此,将您的第二个案例声明移到第一个案例声明之前,就可以了。 请注意,这就是为什么在模式匹配中,更具体的匹配用例需要排在最前面,而更一般的case语句必须排在最后。     

要回复问题请先登录注册