【问题标题】:What is the return type of a scala if statement without else没有else的scala if语句的返回类型是什么
【发布时间】:2017-08-11 05:35:04
【问题描述】:

我在一些 Scala 代码中犯了类似以下的错误:

val someVal:String = if (someX == someY) n

回想起来,我很清楚这个错误(它必须为 someVal 分配一些东西,如果表达式为假,它可能不会是字符串)。我想知道如果表达式为假,返回的值是什么。我最好的猜测是 Unit,或者 AnyVal。

【问题讨论】:

  • 如果您查看编译该代码时遇到的编译器错误,它会准确地告诉您 RHS 表达式的类型。

标签: scala types


【解决方案1】:

该代码将无法编译,因为someVal 是一个字符串,那么每个执行路径(ifelse)都必须返回一个字符串。但是,由于您没有else,因此这是不可能的,因此无法编译。

编译器错误将如下所示,这表明您在应该返回String时返回Unit

error: type mismatch;
 found   : Unit
 required: String

那是因为你所拥有的就相当于这个:

val someVal: String = if (foo == bar) "Hello World" else ()

()Unit 的唯一值,它不是 String 类型的有效值。

将来你可以使用 Scala repl 并让它告诉你类型(只是不要指定一个):

scala> val someVal1 = if (true) "Hello World" 
someVal1: Any = Hello World

val someVal2 = if (false) "Hello World" 
someVal2: Any = ()

如您所见,类型是Any,因为这是UnitString 之间唯一的共同父对象:

【讨论】:

  • 我想你误解了我的问题......我明白为什么我的代码是错误的,我只想知道如果语句评估为 false 的返回类型是什么。我相信你提到的最后一部分是 (),对吗?
  • 您拥有的代码无法编译,因此无法找到false 的情况。您必须更改为val someVal1: Any,在这种情况下,值将是()
  • 使用 if 而不使用 else 是引入推理问题的不好做法
【解决方案2】:

if 表达式的整体类型将是所有分支中最小的公共超类型。

在您的示例中,真正的路径是String

缺少的 else 与空的 else 相同,都计算为 Unit

UnitString 在完全独立的继承树中,(字符串是AnyRefUnitAnyVal)所以整个表达式的类型是Any,所有的共同超类型Scala 中的类型。

如果真实情况导致AnyVal 类型(例如Int),那么整个表达式的类型将是AnyVal

如果 true case 评估为 Unit(例如,如果您只是在 if 中使用 println 而不是返回值),那么表达式的类型将是 Unit,这是有道理的,因为两个路径都有同类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    • 2016-02-16
    • 2023-02-21
    相关资源
    最近更新 更多