currently i have this:
private def isCollectionLike[T](manifest: Manifest[T]):Boolean = {
manifest.runtimeClass.toString.contains("scala.collection")
}
I don't like this solution, can you purpose a better one?
Just callingClass#isAssignable
should be enough:
def isCollectionLike[T](manifest: Manifest[T]):Boolean = {
classOf[scala.collection.TraversableLike[_,_]].isAssignableFrom(manifest.runtimeClass)
}
Mandatory REPL test:
scala> isCollectionLike(manifest[List[Int]])
res17: Boolean = true
scala> isCollectionLike(manifest[String])
res18: Boolean = false
scala> isCollectionLike(manifest[scala.collection.SeqLike[Int,_]])
res19: Boolean = true
Note though that this won't work with arrays, for the simple reason that scala arrays now (since scala 2.8) map directly to the udnerlying JVM arrays,
and as such do not inherit TraversableLike
(If interested you can have a look at http://docs.scala-lang.org/sips/completed/scala-2-8-arrays.html).
scala> isCollectionLike(manifest[Array[String]])
res20: Boolean = false
So you'll have to handle it as a special case, or find a better way to test for a collection.
As a side note, these days there is an alternative to java reflection scala's own reflection api (and in addition Manifest
is deprecated in favor of TypeTag
),
which has the immense advantage of understanding all the scala specific features
(that Class
instance retruned by runtimeClass
does not know anything about scala).
But it is also more complex, and (currently) not thread safe at all, which is a major limitation.
Plus in your case you will still have to handle arrays as a special case anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With