bendl
bendl

Reputation: 1630

What is the return type of a scala if statement without else

I made a mistake similar to the following in some Scala code:

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

In retrospect the mistake is clear to me (it has to assign something to someVal, and if the expression is false, it's probably not going to be a string). I want to know what the value returned would be if the expression is false. My best guess is Unit, or perhaps AnyVal.

Upvotes: 3

Views: 5891

Answers (2)

Tyler
Tyler

Reputation: 18157

That code will not compile, because for someVal to be a String, then each execution path (the if and the else) would have to return a String. However since you don't have an else, this is impossible and thus won't compile.

The compiler error will be the following, which is indicating that you are returning a Unit when you are supposed to return String:

error: type mismatch;
 found   : Unit
 required: String

That's because what you have is equivalent to this:

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

() is the only value of Unit, which is not a valid value for a String type.

In the future you can use the Scala repl and have it tell you the types (just don't specify one):

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

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

As you can see the type is Any because that is the only common parent between Unit and String:

Class Hierarchy

Upvotes: 12

puhlen
puhlen

Reputation: 8519

The type of whole if expression will be the smallest common supertype of all branches.

The true path is String in your example

A missing else is the same as an empty else, both evaluate to Unit.

Unit and String are in completely separate inheritance trees, (String is AnyRef and Unit is AnyVal) so the type of the whole expression is Any, the common super type of all types in Scala.

If the true case resulted in an AnyVal type (for example, Int) then the type of the whole expression would be AnyVal

If the true case evaluated to Unit (for example if you just used println in the if instead of returning a value) then the type of the expression would be Unit which makes sense since both paths have the same type.

Upvotes: 3

Related Questions