while programming some Scala I realized the following:
Map[Int, Option[Int]]().updated(3, None).get(3)
returns
Some(None)
instead of the expected
None
This seems very counterintuitive. Is this expected behavior or is this a bug.
I'm on Scala 2.13.8 by the way.
CodePudding user response:
It's very much expected behavior. Option
is a "data structure" like any other, so there's no special handling of it from the compiler's side. If you associate a None
with a key in that map, then there's an entry there and Map
will report it.
If you want the behavior you expected, then either:
- Don't store values as
Option
s, but instead use the plainInt
type, or flatten
the result at the end:get(3).flatten
.
A similar thing will happen if you put Option
s inside Option
s — there's no automagic flattening:
scala> Option(None)
val res0: Option[None.type] = Some(None)
scala> .flatten
val res1: Option[Nothing] = None
CodePudding user response:
Yes, it is expected behavior as you can clearly see from the signature of Map.get
: def get(key: K): Option[V]
.
In your case, V
is Option[Int]
, so the result of get
is Option[Option[Int]]
.
It is kinda unusual to have Option
as value in a Map, in most cases, it is redundant, because you could just not have an entry in the map at all rather than storing None
.
One use cases I can think of where it would be useful is implementing some kind of a cache: in that case, None
would mean, the entry for the key does not exit, while missing key would indicate that it has not been checked.