简体   繁体   中英

Check if Scala class is instance of T

My application handles a lot of third party integrations. I have an abstract base class for third party integrations which specifies a bunch of methods that an integration class should handle – then certain integrations can be extended with additional functionality that is not available on all integrations.

Basically it looks like this:

abstract class Integration { ... }
trait SingleSignOn { ... }

class NormalIntegration extends Integration {}
class SingleSignOnIntegration extends Integration with SingleSignOn {}

I would like to be able to sort out all integrations that have a specific trait, and this is what I thought of as the basic solution:

val allIntegrations: Seq[Integration] = ...

def integrationsWithTrait[T]: Seq[Integration] = {
  allIntegrations.filter(_.isInstanceOf[T])
}

The usage is:

val singleSignOnIntegrations = integrationsWithTrait[SingleSignOn]

The issue is that isInstanceOf[T] always returns true (meaning I end up with singleSignOnIntegrations == allIntegrations ), while hard coded isInstanceOf[SingleSignOn] works as intended.

How do I fix integrationsWithTrait to work as I intend?

This will work:

def integrationsWithTrait[T](implicit tag: scala.reflect.ClassTag[T]): Seq[Integration] = {
  allIntegrations.filter(tag.runtimeClass.isInstance)
}

Scalac will inject ClassTag instance for every class that this method will be called with. This will allow to access the Class object in runtime and verify if the class is the instance of given class/trait.

I think the original code doesn't work because of type erasure.

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