检查 Scala 匹配表达式中的两个特定异常
Check two specific exceptions in a match expression in Scala
所以我在 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
音高类名称:
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 中的值,我们将获得一个例外)然后我们将先乘以 12 添加 octave: Int = 4
。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 消息:“找不到密钥:K#”
现在如您所见,我在测试 Try 语句的匹配表达式中有一个空的失败案例,在这种情况下,我想检查异常 e 是 AssertionError 还是 NoSuchElementException,以及它是否是其中之一我想打印一些特殊的文字。最后一种情况是针对其他例外情况。但是我不太确定如何测试这个?有什么我可以在失败中写的东西,比如 (e: ???) 有什么想法吗?
您可以为两个例外添加两个 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 中有一个 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
音高类名称:
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 中的值,我们将获得一个例外)然后我们将先乘以 12 添加 octave: Int = 4
。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 消息:“找不到密钥:K#”
现在如您所见,我在测试 Try 语句的匹配表达式中有一个空的失败案例,在这种情况下,我想检查异常 e 是 AssertionError 还是 NoSuchElementException,以及它是否是其中之一我想打印一些特殊的文字。最后一种情况是针对其他例外情况。但是我不太确定如何测试这个?有什么我可以在失败中写的东西,比如 (e: ???) 有什么想法吗?
您可以为两个例外添加两个 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