如何确定一个类是否是父类或特征的子类?

问题描述

在Scala中,我们如何确定某个类是父类还是特征的子类?例如:

trait MyTrait
class MyParentClass()
class MyOtherParentClass()

case class MySubClass() extends MyParentClass with MyTrait
case class MyOtherSubClass() extends MyOtherParentClass

是否可以在不实例化对象和通过反射API的情况下,确定诸如MySubClassMyParentClass之类的类?给定一个未知的泛型类型MyTrait,如果T扩展了特定的父类或特征,我想让它匹配一个案例:

T

解决方法

如果你写

case class MySubClass() extends MyParentClass with MyTrait

然后显然MySubClass扩展了MyParentClassMyTrait,因此您可以使用

检查泛型类型T
def test[T](implicit ev: T <:< MyParentClass,ev1: T <:< MyTrait) = ???

test[MySubClass] // compiles

在编译时。


如果要使用OR而不是AND进行检查,则可以使用shapeless.OrElseimplicitbox.Priority

Scala method that needs either one of two implicit parameters


我用所需用法的示例更新了问题

似乎您想要一个类型类

trait Example[T] {
  def example(): Unit
}
object Example {
  implicit def subtypeOfMyParentClass[T <: MyParentClass] = new Example[T] {
    override def example(): Unit = ???
  }

  implicit def subtypeOfMyOtherParentClass[T <: MyOtherParentClass] = new Example[T] {
    override def example(): Unit = ???
  }

  implicit def subtypeOfMyOtherTrait[T <: MyOtherTrait] = new Example[T] {
    override def example(): Unit = ???
  }

  implicit def default[T] = new Example[T] {
    override def example(): Unit = ???
  }
}

def example[T]()(implicit e: Example[T]): Unit = e.example()

类型类是模式匹配的编译时(即类型级别)替代。

如果隐式对象之间存在歧义,则可以对它们进行优先级排序。


很好奇,您是否知道是否有一种方法可以通过反射API在简单的单行条件(例如if (T extends from MyParentClass) then ...)中进行操作(是否可以通过classOf[]typeOf[]? )

您可以在运行时完成

import scala.reflect.runtime.universe._

def example[T: TypeTag](): Unit = 
  if (typeOf[T] <:< typeOf[MyParentClass]) ???
  else if (typeOf[T] <:< typeOf[MyOtherParentClass]) ???
  else if (typeOf[T] <:< typeOf[MyOtherTrait]) ???
  else ???

import scala.reflect.ClassTag

def example[T: ClassTag](): Unit = 
  if (classOf[MyParentClass] isAssignableFrom classOf[T]) ???
  else if (classOf[MyOtherParentClass] isAssignableFrom classOf[T]) ???
  else if (classOf[MyOtherTrait] isAssignableFrom classOf[T]) ???
  else ???

或在编译时

import scala.language.experimental.macros
import scala.reflect.macros.blackbox

def example[T](): Unit = macro exampleImpl[T]

def exampleImpl[T: c.WeakTypeTag](c: blackbox.Context)(): c.Tree = {
  import c.universe._

  if (weakTypeOf[T] <:< typeOf[MyParentClass]) ???
  else if (weakTypeOf[T] <:< typeOf[MyOtherParentClass]) ???
  else if (weakTypeOf[T] <:< typeOf[MyOtherTrait]) ???
  else ???
}

但是隐式和类型是一种更好的方式,而不是(编译时或尤其是运行时)反射。目前尚不清楚为什么您需要反思。

https://users.scala-lang.org/t/how-to-access-the-method/6281

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...