简体   繁体   中英

determine if T of Manifest[T] is a collection

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 calling Class#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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM