8
scala> val s: Seq[Class[_ <: java.lang.Enum[_]]] = Seq(classOf[java.util.concurrent.TimeUnit])
s: Seq[Class[_ <: java.lang.Enum[_]]] = List(class java.util.concurrent.TimeUnit)

scala> s.flatMap(_.getEnumConstants)
<console>:9: error: no type parameters for method flatMap: (f: Class[_ <: java.lang.Enum[_]] => scala.collection.GenTraversableOnce[B])(implicit bf: scala.collection.generic.CanBuildFrom[Seq[Class[_ <: java.lang.Enum[_]]],B,That])That exist so that it can be applied to arguments (Class[_ <: java.lang.Enum[_]] => scala.collection.mutable.ArrayOps[_$1(in value $anonfun) with java.lang.Object] forSome { type _$1(in value $anonfun) <: java.lang.Enum[_] })
 --- because ---
argument expression's type is not compatible with formal parameter type;
 found   : Class[_ <: java.lang.Enum[_]] => scala.collection.mutable.ArrayOps[_$1(in value $anonfun) with java.lang.Object] forSome { type _$1(in value $anonfun) <: java.lang.Enum[_] }
 required: Class[_ <: java.lang.Enum[_]] => scala.collection.GenTr...              s.flatMap(_.getEnumConstants)
4

2 回答 2

6

不是真正的准确答案,但有两个观察结果 - Scala 2.10 会给你一个更好的错误:

scala> s.flatMap(_.getEnumConstants)
<console>:9: error: no type parameters for method flatMap: (f: Class[_ <: Enum[_]] => scala.collection.GenTraversableOnce[B])(implicit bf: scala.collection.generic.CanBuildFrom[Seq[Class[_ <: Enum[_]]],B,That])That exist so that it can be applied to arguments (Class[_ <: Enum[_]] => scala.collection.mutable.ArrayOps[(some other)_$1(in object $iw) with Object] forSome { type (some other)_$1(in object $iw) <: Enum[_] })
 --- because ---
argument expression's type is not compatible with formal parameter type;
 found   : Class[_ <: Enum[_]] => scala.collection.mutable.ArrayOps[(some other)_$1(in object $iw) with Object] forSome { type (some other)_$1(in object $iw) <: Enum[_] }
 required: Class[_ <: Enum[_]] => scala.collection.GenTraversableOnce[?B]
              s.flatMap(_.getEnumConstants)
                ^
<console>:9: error: type mismatch;
 found   : Class[_ <: Enum[_]] => scala.collection.mutable.ArrayOps[(some other)_$1(in object $iw) with Object] forSome { type (some other)_$1(in object $iw) <: Enum[_] }
 required: Class[_ <: Enum[_]] => scala.collection.GenTraversableOnce[B]
              s.flatMap(_.getEnumConstants)
                          ^
<console>:9: error: Cannot construct a collection of type That with elements of type B based on a collection of type Seq[Class[_ <: Enum[_]]].
              s.flatMap(_.getEnumConstants)
                   ^

而且,如果你拆分你的flatMap,你会看到一个更简单的问题版本:

scala> s.map(_.getEnumConstants)
res28: Seq[Array[_$1 with Object] forSome { type _$1 <: Enum[_] }] = List(Array(NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS), Array(RELEASE_0, RELEASE_1, RELEASE_2, RELEASE_3, RELEASE_4, RELEASE_5, RELEASE_6))
scala> res28.flatten
<console>:10: error: No implicit view available from Array[_$1 with Object] forSome { type _$1 <: Enum[_] } => scala.collection.GenTraversableOnce[B].
              res28.flatten
                    ^

这是相当令人惊讶的,因为您会认为将 anArray变成. 应该很容易GenTraversableOnce。我目前没有时间挖掘细节,但我会指出以下事情似乎有效:

s.flatMap(_.getEnumConstants.toSeq)
s.flatMap(_.getEnumConstants.map(_.asInstanceOf[Enum[_]]))

我投票编译器错误,因为这个 gist,它在这个简单脚本的 REPL 中显示了一些非常奇怪的行为

val s: Seq[Class[_ <: java.lang.Enum[_]]] = Seq(classOf[java.util.concurrent.TimeUnit], classOf[javax.lang.model.SourceVersion])
s.flatMap(_.getEnumConstants.toSeq)
s.flatMap(_.getEnumConstants.toArray)
1234
于 2013-03-12T09:21:05.020 回答
2

TimeUnit.getEnumConstants返回一个 java 数组TimeUnit[],而flatMap期望一个GenTraversable

你可以通过

scala> s.flatMap(_.getEnumConstants.toSeq)
res4: Seq[Enum[_]] = List(NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS, DAYS)
于 2013-03-12T09:18:11.417 回答