Scala Опция: сопоставление и соответствие шаблонов

Имея дело с Option в Scala, каковы вещи, которые я должен рассмотреть, чтобы решить, сопоставлять ли карту или паттен? Например, если у меня есть Option[MyClass], я могу справиться с ним следующими способами:

def getList(myOptionInstance: Option[MyClass]): List[String] =
  myOptionInstance map (...) getOrElse(List.empty[String])

или

def getList(myOptionInstance: Option[MyClass]): List[String] = myOptionInstance match {
  case Some(mySomeInstance) => .....
  case None => List.empty[String]
}

Когда я буду выбирать один над другим?

Ответ 1

I второй @rarry: fold - это лучший способ справиться с этим.

Некоторые предпочитают сопоставление шаблонов, потому что это "круто" (что бы это ни значило), а иногда и легче читать.

Я стараюсь избегать использования getOrElse, потому что это не заставляет вас использовать тот же тип для значения по умолчанию, что и тип, завернутый в ваш Option:

def getOrElse[B >: A](default: ⇒ B): B

Итак, вы можете написать:

val v = Some(42).getOrElse("FortyTwo")

Здесь v имеет тип Any. Очень легко увидеть проблему с таким глупым примером, но иногда это не так очевидно и может привести к проблемам.

Пока fold:

def fold[B](ifEmpty: ⇒ B)(f: (A) ⇒ B): B

Это заставляет вас возвращать один и тот же тип для обеих ветвей.

scala> Some(42).fold("fortyTwo")(v => v)
<console>:8: error: type mismatch;
 found   : Int
 required: String
              Some(42).fold("fortyTwo")(v => v)

Ответ 2

Соответствие шаблону:

  • немного более эффективный
  • не анал о подтипах (в этом случае @rarry пришлось добавить подсказку типа)
  • легче читать
  • одобрен Мартином Одеркси: fooobar.com/questions/154206/...

Ответ 3

Я бы пошел на это:

myOptionInstance.fold(Nil: List[String])(...)