2016-10-17 6 views
0

(только начал с Scala несколько недель назад, так что медведь со мной)получение java.io.Serializable из опции [..] в Scala

Чтение/попробовать эту маленькую статью здесь, столкнулись с некоторыми неожиданностями

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

После определения класса пользователя случай, как описано:

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 
} 

, вот получает я наблюдаю:

> 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 

Первые два - это то, что я ожидал, но второй второй нет; как для существующих, так и для несуществующих пользователей. Почему java.io.Serializable, внезапно?

ответ

3

Чтобы понять это, вы должны понять, что getOrElse

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

getOrElse определяется на Option. Option может быть Some(value) или None.

getOrElse возвращается default, когда option является none

val map = Map(1 -> 2)

map.get(1) возвращается 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 

Переходя к точке

Some(a).getOrElse(b)

если a и b имеют тот же тип, то результирующий тип будет a типа или b типа

если a и b являются not того же типа, то результирующий тип будет ближайший общий супер тип, который java.io.Serializable в вашем случае ,

Обратите внимание, что

1) ближайший общий супер типа для User и строк является Сериализуемым

2) ближайшим общего супер типа для User и Int является любым

+0

вот, это _exactly_ то, что я думал после того, как задал вопрос. Я ожидал, что это будет «Any», хотя, как и в вашем примере «Some (1) .getOrElse (« Привет »), но я полагаю, что он возвращается к иерархии классов Java, а? – alexakarpov

+0

@alexakarpov, потому что ближайший общий тип супер для пользователя и строки является Serializable – pamu