检查 Scala 匹配表达式中的两个特定异常

Posted

技术标签:

【中文标题】检查 Scala 匹配表达式中的两个特定异常【英文标题】:Check two specific exceptions in a match expression in Scala 【发布时间】:2022-01-12 20:25:11 【问题描述】:

所以我在 Scala 中有一个 Try 块

  def fromString(s: String): Option[Pitch] = scala.util.Try 
    val (pitchClassName, octaveName) = s.partition(c => !c.isDigit)
    val octave = if octaveName.nonEmpty then octaveName.toInt else 5
    Pitch(pitchClassIndex(pitchClassName) + octave  * 12)
   match 
    case scala.util.Success(value) => Some(value)
    case scala.util.Failure(e) => 
    case scala.util.Failure(e) => throw e
  

现在,我知道这里有很多代码需要解释。出于这个问题的目的,尽管需要知道的是:

当使用“D#4”之类的给定音符创建 Pitch 实例时,我可能要专门处理两种不同的异常。第一个是如果 Map pitchClassIndex 找不到给定的键 pitchClassName,第二个是如果 Pitch 参数超出给定范围。

pitchClassIndex:

val pitchClassIndex: Map[String, Int] = pitchClassNames.zipWithIndex.toMap

pitchClassNames:

val pitchClassNames: Vector[String] = Vector("C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B")

所以现在我们输入s: String 并检查它是否有数字,如果有则将其拆分为元组val (pitchClassName, octaveName) 如果s = "D#4" 元组现在是("D#", "4") val octave = 4 所以现在在创建我们的 Pitch 实例时,我们将从键 pitchClassName: String = "D#" 中获取 pitchClassIndex: Map[String, Int] 中的值(请注意,如果 pitchClassName 不对应于 pitchClassNames 中的值,我们将得到一个异常)我们将然后加上octave: Int = 4先乘以12。Pitch(51) 现在 Pitch 的前两行如下所示:

case class Pitch(nbr: Int):
  assert((0 to 127) contains nbr, s"Error: nbr $nbr outside (0 to 127)")

所以如果传入 Pitch 的参数超出(0 to 127) 的范围,则抛出带有错误消息的 AssertionError。

所以现在我们有两种可以抛出异常的情况,第一种是开头的断言。第二个是如果pitchClassIndex(pitchClassName) 采用不包含在pitchClassNames: Vector[String] 中的键,例如“K#”。然后它会抛出一个 NoSuchElementException 消息:“key not found: K#”

现在你可以看到我在测试 Try 语句的匹配表达式中有一个空的失败案例,在这种情况下,我想检查异常 e 是 AssertionError 还是 NoSuchElementException ,如果它是其中之一,我想打印一些特殊的文字。最后一种情况是其他例外情况。但是我不太确定如何测试这个?有什么我可以在失败中写的东西,比如(e:???)有什么想法吗?

【问题讨论】:

【参考方案1】:

您可以为这两个例外添加两个 case 子句

case Failure(e: AssertionError) => 
  // do something
case Failure(e: NoSuchElementException) => 
  // do something else
case Failure(e) =>
  // goes here for other exceptions

如果您想将它们组合成一个案例,您将无法再在变量e 中捕获详细信息,因此这可能不是一种选择:

case Failure(_: AssertionError) 
      | Failure(_: NoSuchElementException)     => 
   // cannot use `e` anymore 

我想你可以求助于.isInstanceOf

case Failure(e) 
  if e.isInstanceOf[AssertionError] ||
     e.isInstanceOf[NoSuchElementException] =>
   // now `e` is Throwable in here  

【讨论】:

以上是关于检查 Scala 匹配表达式中的两个特定异常的主要内容,如果未能解决你的问题,请参考以下文章

python基础之正则表达式

js正则表达式 匹配两个特定字符间的内容

搜索 2 个特定字母后跟 4 个数字 Regex

检查字符串是不是与python中的IP地址模式匹配?

【Scala】模式匹配和样本类

匹配两个特定子字符串之一之前或之后的数字子字符串