简体   繁体   中英

Scala reflection with parameterized types

I've written the following function to check whether a given singleton class implements a trait.

/** Given a singleton class, returns singleton object if cls implements T.                                                 
 * Else returns None. */
 def maybeMakeSingletonObj[T: ClassManifest](cls: Class[_]): Option[T] = {
   try {
     val m = classManifest[T]
     val obj = cls.getField("MODULE$").get(m.erasure).asInstanceOf[AnyRef]

     if (Manifest.singleType(obj) <:< m) Some(obj.asInstanceOf[T])
     else None
   } catch {
     case e: Exception => None
   }
 }

This code works fine on the following example:

trait A
object B extends A

assert(maybeMakeSingletonObj[A](B.getClass()) === Some(B)) 

However, fails on the following example:

trait A[T, R]
object B extends A[Int, Int]

assert(maybeMakeSingletonObj[A[_,_]](B.getClass()) === Some(B))

Any ideas?

From ScalaDoc : "The type-relation operators <:< and =:= should be considered approximations only, as there are numerous aspects of type conformance which are not yet adequately represented in manifests." Apparently, this is one such case.

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