Scala:当模式匹配密封特征时,编译器不会发出警告

时间:2016-02-07 21:28:49

标签: scala pattern-matching traits sealed

这是一个片段。模式匹配时,编译器不发出警告。你知道任何解决方法吗?

我希望编译器在忘记与#menu-left li:hover > ul { width: 150px; margin-left: -50px; } SimpleExpr.Expr进行模式匹配的情况时发出警告。这个结构允许我考虑两个表达式树共有的节点(如OtherExpr.Expr

If

2 个答案:

答案 0 :(得分:1)

因为sealed不是传递性的,所以我不清楚是否缺少编译错误是错误的。

我注意到在match表达式中添加另一个案例会导致编译器发出“无法访问的代码”警告。这是我修改后的代码版本:

#!/usr/bin/env scala
Demo.main(args)

sealed trait Hierarchy {
  sealed trait Expr
}
trait If {
  this: Hierarchy =>
  case class If(cond: Expr, yes: Expr, no: Expr) extends Expr
}
trait Word {
  this: Hierarchy =>
  case class Word(name: String) extends Expr
}

object SimpleExpr extends Hierarchy with If with Word
//object OtherExpr extends Hierarchy with If with Integer

object Demo extends App {
  import SimpleExpr._
  def func(expr: Expr) = expr match {
    case If(cond, yes, no) => cond
    // compiler should emit warning
    case Word(name) => printf("word[%s]\n",name)
  }
  func(Word("yo!"))
}

这是我运行时得到的结果:

warning: unreachable code
case Word(name) => printf("word[%s]\n",name)
one warning found
word[yo!]

警告不正确,正在执行 unreachable 代码。

case Word行被注释掉时,这就是我得到的:

scala.MatchError: Word(yo!) (of class Main$$anon$1$Word$Word)
    at Main$$anon$1$Demo$.func(demo.sc:21)

但是,以下内容确实发出了所需的警告:

#!/usr/bin/env scala
Demo.main(args)

sealed trait Expr
case class Word(name: String) extends Expr
case class If(cond: Expr, yes: Expr, no: Expr) extends Expr

trait Hierarchy
trait IfExpr {
  this: Hierarchy =>
}
trait WordExpr {
  this: Hierarchy =>
}

object SimpleExpr extends Hierarchy with IfExpr with WordExpr
//object OtherExpr extends Hierarchy with If with Integer

object Demo extends App {
  import SimpleExpr._
  def func(expr: Expr) = expr match {
    case If(cond, yes, no) => cond
    // compiler should emit warning
    // case Word(name) => printf("word[%s]\n",name)
  }
  // func(Word("yo!"))
}

以下是我收到的警告:

demo.sc:22: warning: match may not be exhaustive.
It would fail on the following input: Word(_)
  def func(expr: Expr) = expr match {
                     ^

答案 1 :(得分:0)

我终于找到了达到预期效果的解决方案:

trait Hierarchy {
  sealed trait Expr
  case class Unit() extends Expr
}
trait AddIf extends Hierarchy {
  case class If(cond: Expr) extends Expr
}
trait AddWord extends Hierarchy {
  case class Word(name: String) extends Expr
}
trait AddSymb extends Hierarchy {
  case class Symb(name: String) extends Expr
}


object AST1 extends Hierarchy with AddIf
object AST2 extends Hierarchy with AddSymb with AddIf


object TestMatch extends App {
  def match1(e: AST1.Expr) = e match {
    case AST1.If(cond) => 1
  }
  def match2(e: AST2.Expr) = e match {
    case AST2.If(cond) => 1
    case AST2.Unit() => 1
  }
}