alexakarpov alexakarpov - 1 month ago 6
Scala Question

getting a java.io.Serializable from Option[..] in Scala

(just started with Scala a few weeks ago, so bear with me)

Reading/trying out this little article here, ran into some surprises

http://danielwestheide.com/blog/2012/12/19/the-neophytes-guide-to-scala-part-5-the-option-type.html

After defining a case class User as described:

case class User(
id: Int,
firstName: String,
lastName: String,
age: Int,
gender: Option[String])

object UserRepository {
private val users = Map(1 -> User(1, "John", "Doe", 32, Some("male")),
2 -> User(2, "Johanna", "Doe", 30, None))
def findById(id: Int): Option[User] = users.get(id)
def findAll = users.values
}


, here are the gets I observe:

> scala> UserRepository.findById(1)
> res34: Option[User] = Some(User(1,John,Doe,32,Some(male)))
>
> scala> UserRepository.findById(1).get
> res35: User = User(1,John,Doe,32,Some(male))
>
> scala> UserRepository.findById(1).getOrElse("N/A")
> res36: java.io.Serializable = User(1,John,Doe,32,Some(male))
>
> scala> UserRepository.findById(3).getOrElse("N/A")
> res37: java.io.Serializable = N/A


The first two are what I expected, but the second two aren't; both the case of existing and non-existing Users. Why java.io.Serializable, all of the sudden?

Answer

To understand this you have to understand what is getOrElse

final def getOrElse[B >: A](default: => B): B

getOrElse is defined on Option. Option can be Some(value) or None.

getOrElse returns default when option is none

val map = Map(1 -> 2)

map.get(1) returns option

scala> Some(1).getOrElse(2)
res3: Int = 1

scala> Some(1).getOrElse("Hello")
res4: Any = 1


scala> case class User(name: String)
defined class User

scala> (None: Option[User]).getOrElse("a")
res12: java.io.Serializable = a

scala> (None: Option[User]).getOrElse(1)
res7: Any = 1

Coming to the point

Some(a).getOrElse(b)

if a and b are of same type then resultant type will be a type or b type

if a and b are not of same type then resultant type will be nearest common super type which is java.io.Serializable in your case.

Note that

1) nearest common super type for User and String is Serializable

2) nearest common super type for User and Int is Any

Comments