Отражение JVM [Scala]: возвращает определенный тип класса на основе сопоставления с образцом во время выполнения - PullRequest
1 голос
/ 14 мая 2019

Я думаю, что где-то недоразумение, что я не могу понять это:

Я хочу, чтобы код, отвечающий за отражение, предоставил мне тип возврата, который я могу сопоставить с шаблоном для остальной части приложения со статической типизацией .

Мне нравится быть безопасным, используя типы ВСЕ время во время компиляции; однако на этот раз я должен использовать отражение в унаследованных целях; и я стараюсь избегать максимально возможного отражения остального кода; если я могу разыграть или использовать asInstanceOf что-то вроде во время выполнения. Вот иерархия классов, с которой я работаю:

 lvl1:                            abstract class A 
                                     /       \
 lvl2:    abstract class B extends A         abstract class C extends A     
                                    /          \
 lvl3[reflection required]:     to reflect class paths

Как вы можете видеть из вышеизложенного, я знаю, что экземпляры отражающих классов ВСЕ или В это время ВСЕ и я не собираюсь переходить к lvl1, так как мне нужны эти возвращаемые типы для дальнейшего сопоставления с образцом по линии.

Итак, сначала иерархия:

abstract class Website
abstract class Stackoverflow extends Website
abstract class Reddit extends Website
abstract class Academia extends Stackoverflow 

Затем я отражаю «Академию» во время выполнения:

val ru = scala.reflect.runtime.universe
val m = ru.runtimeMirror(getClass.getClassLoader)
val im = m.reflect("Academia")

Теперь здесь, если я использую getClass, я получаю объявленные методы для invoke и т. Д .:

 im.getClass.getDeclaredMethods = ???  //Set/get the methods

Однако:

  • Если я хочу сопоставить шаблон с getClass, у меня есть тип Class[_ <: ru.InstanceMirror].
  • Я не могу использовать его экземпляр, так как он java.lang.Class
  • Я использовал WeakType и Recognizer, как уже упоминалось здесь , однако я получаю ru.Type, когда я использую Recognizer:

    //Taken from cited url.
    object Recognizer {
      def recognize[T](x: T)(implicit tag: WeakTypeTag[T]): String =
         tag.tpe match {
           case TypeRef(utype, usymbol, args) => List(utype, usymbol, args).mkString("\n")
         }
      }
    } 
    

Итак, вопрос в том, есть ли способ, которым у меня есть метод, который может иметь эту подпись:

 def reflectionIWant (path: String): Either[B,C] = ???
 //... or in our example case 
 def reflectionIant (path: String): Either[Stackoverflow, Reddit] = ???
...