Scala Option: map vs Pattern Matching

2020-02-23 08:14发布

问题:

While dealing with Option in Scala what are the things I should be considering to decide whether to map or patten match? For example, if I have Option[MyClass], I can deal with it the following ways:

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

or

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

When will I choose one over the other?

回答1:

I second @rarry: fold is the preferred way to deal with this.

Some prefer pattern matching because it's "cool" (whatever it means) and sometimes easier to read.

I try to avoid using getOrElse because it does not force you to use the same type for the default value as the type wrapped in your Option:

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

So you can write:

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

Here v has type Any. It's very easy to see the problem with such a stupid example but sometimes it's not as obvious and can lead to issues.

While fold:

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

It forces you to return the same type for both branches.

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


回答2:

Pattern matching is :

  • slightly more efficient
  • not anal about subtypes (in this case @rarry had to add a type hint)
  • easier to read
  • endorsed by Martin Oderksy: https://stackoverflow.com/a/5332657/578101


回答3:

I would go for this:

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


标签: scala