Получить тип из строки - PullRequest
2 голосов
/ 19 июня 2019

Я пытаюсь переключить свой код на компонентно-ориентированный дизайн.

Моя точка зрения - следующая функция do(), которая сопоставляет свой аргумент s с некоторыми ранее известными String s ивызывает compute() с соответствующим параметром типа.


  def do(s: String, summoner: Summoner): String = {
      s match {
        case "a" => summoner.compute[Type_A](outOfScopeVal)
        case "b" => summoner.compute[Type_B](outOfScopeVal)
        case _   => ""
      }
    }

Я бы хотел перенести его в общий trait, который может быть extended, если требуется какой-либо новый Type_x.


[EDIT] Это будет библиотека, которую внешние разработчики могут по желанию обогатить, добавив новое соответствие между идентификатором String и типом.

[EDIT2] Я называю библиотеку, определенную следующим образом:


  trait TypeHolder[T <: Type_top] {def score(...): String}

  object Converters {
    implicit object ConverterOfA extends TypeHolder[Type_A] {
      def convertAndMore(...): String = {
        /*
        compute and return a String
        */
      }
    }
    implicit object ConverterOfB extends TypeHolder[Type_B] {
      def convertAndMore(...): String = {
        /*
        compute and return a String
        */
      }
    }
  }

  case class Summoner(...) {
    def compute[T <: Type_top](...)(implicit summoner: TypeHolder[T]): String = {
        summoner.convertAndMore(...)
    }
  }

Эта проблема может быть сведена к получению универсального инструмента, который возвращает (своего рода) type на основе входной строки.

Этот вопрос: https://stackoverflow.com/a/23836385/3896166, приближается к ожидаемому решению, но я не могу соответствовать требованию «заранее знать [имя] типа имен сопоставления объектов», так как входная строка принимается динамически ...

Кроме того,Shapeless может быть путь для подражания, бно я просто начал идти по этому пути.

Возможно ли это?

1 Ответ

1 голос
/ 19 июня 2019

Вы можете решить эту проблему, преобразовав String в type (если бы это было возможно), но это не единственный способ решения вашей основной проблемы.(Следовательно, это XY вопрос )

Вместо этого вам нужно построить Map, который перенесет вас из String в метод, который вычисляет соответствующую функцию.Это может работать примерно так:

def computeFn[T <: Type_top] =
  (summoner: Summoner, value: ???) => summoner.compute[T](value)

val computeMap = Map(
  "a" -> computeFn[Type_A],
  "b" -> computeFn[Type_B]
)

def do(s: String, summoner: Summoner): String =
  computeMap(s)(summoner, outOfScopeVal)

Адаптировать это так просто, чтобы подклассы могли добавить объект computeMap для определения своих собственных отображений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...