为什么这个flatMap失败了?

Rya*_*pte 7 scala

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)
Run Code Online (Sandbox Code Playgroud)

the*_*mel 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)
                   ^
Run Code Online (Sandbox Code Playgroud)

而且,如果你拆分你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
                    ^
Run Code Online (Sandbox Code Playgroud)

这是相当令人惊讶的,因为你认为应该很容易Array变成一个GenTraversableOnce.我现在没有时间挖掘细节,但我会指出以下事情似乎有效:

s.flatMap(_.getEnumConstants.toSeq)
s.flatMap(_.getEnumConstants.map(_.asInstanceOf[Enum[_]]))
Run Code Online (Sandbox Code Playgroud)

我投票编译错误,因为这个要点,它在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
Run Code Online (Sandbox Code Playgroud)