【问题标题】:An exception throw has type `Nothing`?异常抛出的类型为“Nothing”?
【发布时间】:2017-06-18 09:28:56
【问题描述】:

如此处所述 - Chapter 7 of Programming in Scala, Built-in Control Structures, 7.4 Exception handling with try expressions:

在 Scala 中,throw 是一个具有结果类型的表达式。

从技术上讲,异常抛出的类型为 Nothing。您可以将 throw 用作表达式,即使它实际上永远不会计算出任何值。这一点技术体操听起来可能很奇怪,但在像前面的例子这样的情况下经常有用。 if 的一个分支计算一个值,而另一个抛出异常并计算Nothing。整个 if 表达式的类型就是计算某些东西的那个分支的类型。

例子是:

val half =
  if (n % 2 == 0)
    n / 2
  else
    throw new RuntimeException("n must be even")

然后我去了 Scala 并尝试:

scala> val n = 1
n: Int = 1

scala> val half = if (n % 2 == 0) n / 2 else throw new RuntimeException("n must be even")
java.lang.RuntimeException: n must be even
  ... 29 elided

scala> half
<console>:12: error: not found: value half
       half
       ^

表示找不到half。但是,根据这本书,我认为它应该说它是已定义的,并且它的类型为Nothing

这里有什么问题?

【问题讨论】:

    标签: scala exception throw


    【解决方案1】:

    这是说没有找到一半。但是,根据这本书,我 假设它应该说它已定义并且类型为 Nothing。

    如果你重读那一段,你会发现half的类型不应该是Nothing,而应该是Int

    整个if表达式的类型就是那个分支的类型 它确实计算了一些东西。

    计算值的分支产生Int 类型。您可以通过将half 定义为方法而不是值来证明这一点:

    scala> def half = if (n % 2 == 0) n / 2 else throw new RuntimeException("n must be even")
    half: Int
    

    如果您真的想查看 throw 的类型为 Nothing,请将其添加到您的 IDE 中并使其显示类型:

    val exception: Nothing = throw new RuntimeException("n must be even")
    

    关于half,没有找到,因为它的声明抛出异常,导致REPL无法绑定值。

    【讨论】:

    • 我的问题是,正如书中所述:throw 是一个具有结果类型的表达式。但是,异常抛出没有任何类型的 val。
    • @ChangLiu 它确实有一个值,您根本看不到它,因为该值从未初始化(因为它在初始化时引发异常)。可以看到使用方法定义(def)或者函数,可以看到返回类型是Int
    • 如果从来没有初始化过,那么an exception throw has type Nothing这个语句是从哪里来的呢? Nothing 类型显示在哪里?换句话说,有没有办法证明Nothing这个类型?
    猜你喜欢
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-26
    相关资源
    最近更新 更多