斯卡拉模式匹配一​​直说"匹配并不详尽!"

ste*_*nos 9 scala match

我想利用Scala在缺少匹配时发出的警告("不详尽") - 这样我就不会忘记一个(我有几十个).以下简化示例显示了我的尝试:

sealed case class MESSAGE()
class SUCCESS_MESSAGE extends MESSAGE
class FAILURE_MESSAGE extends MESSAGE

def log(str: String, msgType: MESSAGE) {
    msgType match {
        case t:SUCCESS_MESSAGE => println("FAILURE: " + str)
        case t:FAILURE_MESSAGE => println("SUCCESS: " + str)
    }
}
Run Code Online (Sandbox Code Playgroud)

问题在于它说"匹配并不详尽!" 虽然列出了所有可能的组合.如果我把"case _ =>"放在那里,警告的全部内容对我来说都是无效的,因为我可以添加

class INFO_MESSAGE extends MESSAGE
Run Code Online (Sandbox Code Playgroud)

并且不会发出警告.

有解决方案吗?

Kev*_*ght 33

理想情况下,您不应该扩展具体类,尤其不是案例类!

由于没有潜在的定制SUCCESS_MESSAGEFAILURE_MESSAGE,你可能也希望让这些单身.

最后,下划线是Scala变量或类名中的Bad Thing(tm).所有UPPERCASE名称也不是惯用语.所以:

sealed trait Message
case object SuccessMessage extends Message
case object FailureMessage extends Message

def log(str: String, msgType: Message) = msgType match {
  case SuccessMessage => println("Success: " + str)
  case FailureMessage => println("Failure: " + str)
}
Run Code Online (Sandbox Code Playgroud)

或者,我推荐这一点,你可以用实际的消息字符串:

sealed trait Message { def msg: String }
case class Success(msg:String) extends Message
case class Failure(msg:String) extends Message

def log(msg: Message) = msg match {
  case Success(str) => println("Success: " + str)
  case Failure(str) => println("Failure: " + str)
}
Run Code Online (Sandbox Code Playgroud)

  • 第一个例子仍然遇到同样的问题,因为`Message`没有标记为`abstract`.第二个例子是可以的,因为抽象方法`msg`保证`Message`也是抽象的. (2认同)

sep*_*p2k 31

您错过了一个案例:消息可能是一个实例MESSAGE,而不是其子类之一.

如果你想让这个案子不可能,你需要MESSAGE抽象.这将使警告消失.