Можно ли сопоставить тип манифеста в Scala? - PullRequest
3 голосов
/ 30 января 2012

Я пишу некоторый код в Scala, который зависит от параметра типа, который я не вижу в аргументе.

def read[T](json: String)(implicit m: Manifest[T]): T = {
  if (m <:< manifest[Map[String, Any]]) {
    JsonParser.jsonToMap(json).asInstanceOf[T]
  } else {
    throw new UnsupportedOperationException("Not implemented for type %s".format(m))
  }
}

Помимо того, что я пишу свой собственный фреймворк json, что, вероятно, довольно плохая идея ...

Могу ли я использовать оператор case вместо операторов if или я должен думать в другом направлении?

1 Ответ

6 голосов
/ 30 января 2012

Гораздо лучшая идея в ситуациях, подобных этим, где вы испытываете желание использовать последовательности тестов для манифестов или классов (или в общем случае для определения типов), - это использовать класс типов.В данном конкретном случае это будет выглядеть так:

// Type class
trait JsonReader[T] {
  def apply(json : String) : T
}

// Type class instance for type Map[String, Any]
implicit def mapReader = new JSonReader[Map[String, Any]] {
  def apply(json : String) =
    JsonParser.jsonToMap(json).asInstanceOf[Map[String, Any]]
}

def read[T](json : String)(implicit reader : JsonReader[T]) : T = reader(json)

Вы должны добавить экземпляры типов для всех типов, которые вас интересуют.

Теперь вы можете вызывать функцию чтения следующим образом:

read[Map[String, Any]](... some json ...)

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

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