alexakarpov alexakarpov - 11 months ago 64
Scala Question

getting a 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

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: = User(1,John,Doe,32,Some(male))
> scala> UserRepository.findById(3).getOrElse("N/A")
> res37: = 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, all of the sudden?

Answer Source

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: = a

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

Coming to the point


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 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