Why is foreach better than get for Scala Options?

前端 未结 6 421
深忆病人
深忆病人 2021-01-31 07:31

Why using foreach, map, flatMap etc. are considered better than using get for Scala Options? If I useisEmpty I c

相关标签:
6条回答
  • 2021-01-31 08:08

    Put simply:

    • If you need to do something (a procedure when you don't need to capture the return value of each invocation) only if the option is defined (i.e. is a Some): use foreach (if you care about the results of each invocation, use map)

    • If you need to do something if the option defined and something else if it's not: use isDefined in an if statement

    • If you need the value if the option is a Some, or a default value if it is a None: use getOrElse

    0 讨论(0)
  • 2021-01-31 08:11

    Trying to perform our Operations with get is more imperative style where u need to tel what to do and how to do . In other words , we are dictating things and digging more into the Options internals. Where as map,flatmap are more functional way of doing things where we are say what to do but not how to do.

    0 讨论(0)
  • 2021-01-31 08:19

    There are already excellent answers to the actual question, but for more Option-foo you should definitely check out Tony Morris' Option Cheat Sheet.

    0 讨论(0)
  • 2021-01-31 08:25

    The reason it's more useful to apply things like map, foreach, and flatMap directly to the Option instead of using get and then performing the function is that it works on either Some or None and you don't have to do special checks to make sure the value is there.

    val x: Option[Int] = foo()
    val y = x.map(_+1) // works fine for None
    val z = x.get + 1  // doesn't work if x is None
    

    The result for y here is an Option[Int], which is desirable since if x is optional, then y might be undetermined as well. Since get doesn't work on None, you'd have to do a bunch of extra work to make sure you didn't get any errors; extra work that is done for you by map.

    0 讨论(0)
  • 2021-01-31 08:28

    One nice reason to use foreach is parsing something with nested options. If you have something like

    val nestedOption = Some(Some(Some(1)))
    for {
      opt1 <- nestedOption
      opt2 <- opt1
      opt3 <- opt2
    } println(opt3)
    

    The console prints 1. If you extend this to a case where you have a class that optionally stores a reference to something, which in turn stores another reference, for comprehensions allow you to avoid a giant "pyramid" of None/Some checking.

    0 讨论(0)
  • 2021-01-31 08:35

    Well, it kind of comes back to "tell, don't ask". Consider these two lines:

    if (opt.isDefined) println(opt.get)
    // versus
    opt foreach println
    

    In the first case, you are looking inside opt and then reacting depending on what you see. In the second case you are just telling opt what you want done, and let it deal with it.

    The first case knows too much about Option, replicates logic internal to it, is fragile and prone to errors (it can result in run-time errors, instead of compile-time errors, if written incorrectly).

    Add to that, it is not composable. If you have three options, a single for comprehension takes care of them:

    for {
      op1 <- opt1
      op2 <- opt2
      op3 <- opt3
    } println(op1+op2+op3)
    

    With if, things start to get messy fast.

    0 讨论(0)
提交回复
热议问题