加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala – 意外类型从Map切换到Iterable进行理解?

发布时间:2020-12-16 18:17:26 所属栏目:安全 来源:网络整理
导读:为了理解地图,我对幕后打字感到困惑.我的理解是外部集合类型通常应该被保留,我们在以下两种情况下看到预期的行为: scala for { | (k,v) - Map(0-1,2-3) | } yield k - vres0: scala.collection.immutable.Map[Int,Int] = Map(0 - 1,2 - 3)scala for { | (k,
为了理解地图,我对幕后打字感到困惑.我的理解是外部集合类型通常应该被保留,我们在以下两种情况下看到预期的行为:

scala> for {
     |   (k,v) <- Map(0->1,2->3)
     | } yield k -> v
res0: scala.collection.immutable.Map[Int,Int] = Map(0 -> 1,2 -> 3)

scala> for {
     |   (k,2->3)
     |   foo = 1
     | } yield k -> v
res1: scala.collection.immutable.Map[Int,2 -> 3)

但是当我在for comprehension中添加第二个作业时,我得到了一些令人惊讶的东西:

scala> for {
     |   (k,2->3)
     |   foo = 1
     |   bar = 2
     | } yield k -> v
res2: scala.collection.immutable.Iterable[(Int,Int)] = List((0,1),(2,3))

为什么会这样?

解决方法

如果您运行scala -Xprint:typer -e“for {…} yield k-> v”,您可以获得代码的去糖化版本.这是你得到的非常简化的版本:

val m: Map[Int,Int] = Map(0->1,2->3)
m.map {
  case x @ (k,v) =>
    val foo = 1
    val bar = 2
    (x,foo,bar)
}.map {
  case ((k,v),bar) => (k,v)
}

所以你会注意到,当for-comprehension转换为.map调用时,它实际上返回foo和bar以及k-> v,这意味着它是一个Tuple3 [(Int,Int),Int,Int ].由于Tuple3对象的可迭代不能转换为Map,因此它假定它必须返回Iterable.但是,为了获得正确的输出,它是Tuple2对象的集合,它执行一个从Tuple3中丢弃foo和bar的辅助.map,但此时它不再知道它应该是一个Map,因为当你链接到.map的调用,信息不会被结转.

只有一个赋值的例子很幸运,因为中间表示是Tuple2 [(Int,Int].

另一方面,如果直接使用.map,它可以工作:

Map(0->1,2->3).map { 
  case (k,v) =>
    val foo = 1
    val bar = 2 
    k -> v
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读