Мне нужно проверить тип любого объекта и получить соответствующий объект.
Тем не менее, T не может быть решена путем передачи его в нормальный функциональный параметр.
Вам нужно сравнивать, пока все параметры типа не совпадут.
trait Wrap[T]
trait Interface
trait InterfaceA extends Interface
trait InterfaceB extends Interface
object InterfaceAImpl extends Wrap[InterfaceA] with Candidate
object InterfaceBImpl extends Wrap[InterfaceB] with Candidate
trait Mediate[T <: Interface] {
val t: T = get[Wrap[T]]
}
object A extends Mediate[InterfaceA]
object B extends Mediate[InterfaceB]
def get[T: c.WeakTypeTag](c: blackbox.Context): c.Expr[Option[T]] = {
import c.universe._
// Find an object that mixes in a specific interface
// Suppose that the result is [[object A]] and [[object B]]
val detected: List[Symbol] = new CandidateExtractor[c.type](c).run[Candidate]
// This result is
// "InterfaceAImpl =:= Wrap[T]"
// "InterfaceBImpl =:= Wrap[T]"
// When called from A, it expects Wrap[InterfaceA] instead of Wrap[T]
detected.foreach(x => println(s"${x.typeSignature} =:= ${weakTypeOf[T]}"))
// Find objects that inherits Wrap [T] among objects that inherit a specific interface
val r = detected.collectFirst {
// Wrap[InterfaceA] and Wrap[T] are compared, so all false.
case x if x.typeSignature =:= weakTypeOf[T] => x
}
c.Expr[Option[T]](
q"$r"
)
}
Есть ли способ сравнить наследственные отношения, в том числе дженерики?
Для второй попытки
В результате я хочу ...
object A
s t: T
= InterfaceAImpl
, поскольку он наследует Wrap[InterfaceA]
object B
s t: T
= InterfaceBImpl
, потому что он наследует Wrap[InterfaceB]
Значит, <:<(typeOf[Wrap[_])
недействительно.
Должно быть <:<(Wrap[_])
и baseClasses.find(Wrap[_]).typeArgs.contains(T (is InterfaceA or InterfaceB))