首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Map#getOrElse的类型怪异

Map#getOrElse的类型怪异
EN

Stack Overflow用户
提问于 2014-09-17 18:26:27
回答 3查看 2.1K关注 0票数 3

考虑一下

代码语言:javascript
运行
复制
scala> val m = Map('a -> 3, 'b -> 4)
m: scala.collection.immutable.Map[Symbol,Int] = Map('a -> 3, 'b -> 4)

scala> val d: Double = m.getOrElse('c, 0)
<console>:8: error: type mismatch;
 found   : AnyVal
 required: Double
       val d: Double = m.getOrElse('c, 0)
                                  ^

scala> m.getOrElse('c, 0)
res0: Int = 0

scala> m.getOrElse('a, 0)
res1: Int = 3

为什么Scala认为getOrElse调用返回AnyVal,即使它显然返回Int

此外,即使这样做也会出现同样的错误:

代码语言:javascript
运行
复制
scala> val x: Double = m.getOrElse('a, 0): Double
<console>:8: error: type mismatch;
 found   : AnyVal
 required: Double
       val x: Double = m.getOrElse('a, 0): Double

然而,这样做是可行的:

代码语言:javascript
运行
复制
scala> val x: Double = m.getOrElse('a, 0): Int
x: Double = 3.0

这种情况发生在2.11.x上,我没有在2.10.x上尝试过。

EN

Stack Overflow用户

发布于 2014-09-17 18:34:04

因为map在其第二类参数中是协变的,所以我们需要使用特殊的技巧来避免反方差问题,即为这种类型指定一个上限:

代码语言:javascript
运行
复制
def getOrElse[B1 >: B](key: A, default: => B1): B1

因为您显式地提供返回类型为Double,所以scalac将其常见的超级类型解析为AnyVal,因为IntDoubleAnyVal的子类型。在第二个例子中,scalac看到了类型归属,因此它正确地推断了B1,然后将Int转换为Double。

票数 6
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25897784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档