Scala 模式匹配一​​直说“匹配并不详尽!”

发布于 2024-09-29 03:14:21 字数 575 浏览 5 评论 0原文

我想利用 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)
    }
}

问题是它说“匹配并不详尽!”尽管列出了所有可能的组合。如果我把“case _ =>”在那里,警告的整个要点对我来说是无效的,因为我可以添加

class INFO_MESSAGE extends MESSAGE

并且不会发出警告。

有解决办法吗?

I want to leverage the warning that Scala issues when a matching is missing ("not exhaustive") - so that I don't forget one (I have dozens). The following simplified example shows my attempt:

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)
    }
}

The problem is that it says "match is not exhaustive!" although all possible combinations are listed. If I'd put the "case _ =>" in there, the whole point of the warning is invalidated for me because I could add

class INFO_MESSAGE extends MESSAGE

and no warning would be issued.

Is there a solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不再见 2024-10-06 03:14:21

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

鉴于无法自定义 SUCCESS_MESSAGEFAILURE_MESSAGE,您可能还想创建这些单例。

最后,下划线在 Scala 变量或类名中是一件坏事。所有大写的名称也不符合惯用语。所以:

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)
}

或者,我建议这样做,您可以包装实际的消息字符串:

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)
}

Ideally, you shouldn't be extending a concrete class, and especially not a case class!

Given that there's no potential to customise SUCCESS_MESSAGE and FAILURE_MESSAGE, you probably also want to make these singletons.

Finally, underscores are a Bad Thing(tm) in Scala variable or class names. All UPPERCASE names are not idiomatic either. So:

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)
}

Alternatively, and I would recommend this, you can wrap the actual message string:

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)
}
分分钟 2024-10-06 03:14:21

您错过了一种情况:消息可能是 MESSAGE 的实例,而不是其子类之一。

如果您想让这种情况成为不可能,您需要将 MESSAGE 抽象化。这将使警告消失。

You missed one case: The message might be an instance of MESSAGE, not one of its subclasses.

If you want to make this case impossible, you need to make MESSAGE abstract. This will make the warning go away.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文