A strange behavior when getOrElse called in scala map

357 views
Skip to first unread message

BillZhang

unread,
Jul 20, 2016, 11:34:34 PM7/20/16
to scala-user
Hi all,
I have a strange question.


scala
> val map = mutable.HashMap[java.lang.Long,java.lang.Long]()
map
: scala.collection.mutable.HashMap[Long,Long] = Map()


scala
> val b = map.getOrElse(1,0L)
b
: Any = 0


scala
> val b:java.lang.Long = map.getOrElse(1,0L)
b
: Long = 0



see above , why b is an Any int the second sentence?

Thank you for explaining why.

Bardur Arantsson

unread,
Jul 20, 2016, 11:44:55 PM7/20/16
to scala...@googlegroups.com
On 07/21/2016 05:34 AM, BillZhang wrote:
> Hi all,
> I have a strange question.
> |
>
>
> scala>val map =mutable.HashMap[java.lang.Long,java.lang.Long]()
> map:scala.collection.mutable.HashMap[Long,Long]=Map()
>
>
> scala>val b =map.getOrElse(1,0L)
> b:Any=0
>
>
> scala>val b:java.lang.Long=map.getOrElse(1,0L)
> b:Long=0
>
> |
>
>
> see above , why b is an Any int the second sentence?
>

It's because "0L" results in a scala.Long not a java.lang.Long. The two
are *not* the same. (And the least common super-type of the two is Any.)

Regards,

BillZhang

unread,
Jul 21, 2016, 12:18:45 AM7/21/16
to scala-user
Thank you, but why implicit conversion did'nt work automaticly ?

Seth Tisue

unread,
Aug 2, 2016, 7:40:53 PM8/2/16
to scala-user
On Wednesday, July 20, 2016 at 9:18:45 PM UTC-7, BillZhang wrote:
> Thank you, but why implicit conversion did'nt work automaticly ?

getOrElse is declared as:
def getOrElse[B1 >: B](key: A, default: ⇒ B1): B1

note that the default isn't constrained to have the same type as the type of values in the map, but may be any supertype of the value type.

when you wrote:
val b = map.getOrElse(1,0L)

you didn't constrain the desired return type, but you did supply a scala.Long (not a java.lang.Long), so the compiler said OK, you must want B1 to be scala.Long then. And the supertype of scala.Long and java.lang.Long is Any, so that's the result type you got.


but when you wrote:
val b: java.lang.Long = map.getOrElse(1,0L)

you asked for B1 to be java.lang.Long. The only way for the compiler to make that typecheck was to convert 0L from scala.Long to java.lang.Long via an implicit conversion.

In general, implicit conversions are not applied unless and until typechecking fails otherwise.

Seth Tisue / Scala team / Lightbend, Inc.
Reply all
Reply to author
Forward
0 new messages