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

scala – 通过调用toSet丢失参数类型错误

发布时间:2020-12-16 18:55:14 所属栏目:安全 来源:网络整理
导读:为什么这段代码不起作用: scala List('a','b','c').toSet.subsets.foreach(e = println(e))console:8: error: missing parameter type List('a','c').toSet.subsets.foreach(e = println(e)) ^ 但是当我拆分它然后它工作正常: scala val itr=List('a','c')
为什么这段代码不起作用:

scala> List('a','b','c').toSet.subsets.foreach(e => println(e))

<console>:8: error: missing parameter type
              List('a','c').toSet.subsets.foreach(e => println(e))
                                                        ^

但是当我拆分它然后它工作正常:

scala> val itr=List('a','c').toSet.subsets
itr: Iterator[scala.collection.immutable.Set[Char]] = non-empty iterator

scala> itr.foreach(e => println(e))
Set()
Set(a)
Set(b)
Set(c)
Set(a,b)
Set(a,c)
Set(b,c)
Set(a,b,c)

这段代码也可以:

Set('a','c').subsets.foreach(e => println(e))

解决方法

首先,有一个更简单的代码版本具有相同的问题:

List('a','c').toSet.foreach(e => println(e))

这也不起作用

List('a','c').toBuffer.foreach(e => println(e))

但是,这些工作正常:

List('a','c').toList.foreach(e => println(e))
List('a','c').toSeq.foreach(e => println(e))
List('a','c').toArray.foreach(e => println(e))

如果你去看看List class documentation,你会看到有效的方法返回一些用A参数化的类型,而不起作用的方法返回类型参数化为B>:A.问题是Scala编译器可以弄清楚要使用哪个B!这意味着如果你告诉它类型它会工作:

List('a','c').toSet[Char].foreach(e => println(e))

至于为什么toSet和toBuffer有这个签名,我不知道……

最后,不确定这是否有用,但这也有效:

// I think this works because println can take type Any
List('a','c').toSet.foreach(println)

更新:稍微调试一下文档后,我注意到该方法适用于所有具有协变类型参数的类型,但具有不变类型参数的方法在返回类型中具有B>:A.有趣的是,尽管Array在Scala中是不变的,但它们提供了两个版本的方法(一个带有A,一个带有B>:A),这就是为什么它没有这个错误.

我也从未真正回答为什么将表达式分成两行.当你自己简单地调用Set时,编译器会自动在结果Set [B]的类型中推断A为B,除非你给它一个特定的类型来选择.这就是类型推断算法的工作原理.然而,当你在混合中抛出另一种未知类型(即你的lambda中的e类型)时,推理算法会窒息而死 – 它只能处理未知的B>:A和未知类型的e也是如此.

(编辑:李大同)

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

    推荐文章
      热点阅读