通过调用 toSet 缺少参数类型错误 [英] missing parameter type error by calling toSet

查看:43
本文介绍了通过调用 toSet 缺少参数类型错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么此代码不起作用:

Why this code doesn't work:

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

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

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

But when I split it then it works fine:

scala> val itr=List('a', 'b', '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', 'b', 'c').subsets.foreach(e => println(e))

推荐答案

首先,有一个更简单的代码版本,但存在同样的问题:

First, there's a simpler version of the code that has the same issue:

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

这也不起作用

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

但是,这些工作得很好:

However, these work just fine:

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

如果你去看看List 类文档 你会看到有效的方法返回一些用 A 参数化的类型,而不起作用的方法返回用 B 参数化的类型>:A.问题是 Scala 编译器无法确定使用哪个 B!这意味着如果你告诉它类型它会起作用:

If you go take a look at the List class documentation you'll see that the methods that work return some type parameterized with A, whereas methods that don't work return types parameterized with B >: A. The problem is that the Scala compiler can't figure out which B to use! That means it will work if you tell it the type:

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

现在至于为什么 toSettoBuffer 有那个签名,我不知道......

Now as for why toSet and toBuffer have that signature, I have no idea...

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

Lastly, not sure if this is helpful, but this works too:

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

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

Update: After poking around the docs a little bit more I noticed that the method works on all the types with a covariant type parameter, but the ones with an invariant type parameter have the B >: A in the return type. Interestingly, although Array is invariant in Scala they provide two version of the method (one with A and one with B >: A), which is why it doesn't have that error.

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

I also never really answered why breaking the expression into two lines works. When you simply call toSet on its own, the compiler will automatically infer A as B in the type for the resulting Set[B], unless you do give it a specific type to pick. This is just how the type inference algorithm works. However, when you throw another unknown type into the mix (i.e. the type of e in your lambda) then the inference algorithm chokes and dies—it just can't handle an unknown B >: A and an unknown type of e as well.

这篇关于通过调用 toSet 缺少参数类型错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆