如何解决如何确定一个类是否是父类或特征的子类?
在Scala中,我们如何确定某个类是父类还是特征的子类?例如:
trait MyTrait
class MyParentClass()
class MyOtherParentClass()
case class MySubClass() extends MyParentClass with MyTrait
case class MyOtherSubClass() extends MyOtherParentClass
是否可以在不实例化对象和通过反射API的情况下,确定诸如MySubClass
或MyParentClass
之类的类?给定一个未知的泛型类型MyTrait
,如果T
扩展了特定的父类或特征,我想让它匹配一个案例:
T
解决方法
如果你写
case class MySubClass() extends MyParentClass with MyTrait
然后显然MySubClass
扩展了MyParentClass
和MyTrait
,因此您可以使用
T
def test[T](implicit ev: T <:< MyParentClass,ev1: T <:< MyTrait) = ???
test[MySubClass] // compiles
在编译时。
如果要使用OR而不是AND进行检查,则可以使用shapeless.OrElse
或implicitbox.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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。