Как я могу сопоставить шаблон на класс времени выполнения в Scala

У меня есть фрагмент кода, подобный этому:

override def getOption[T: TypeTag: ClassTag](path: String): Option[T] = {
  implicitly[scala.reflect.ClassTag[T]].toString() match {
    case "java.lang.String" => HandleBlank(super.getOption[String](path)).asInstanceOf[Option[T]]
    case _ => super.getOption[T](path)
  }
}

Я предполагаю, что должен быть лучший способ сделать это, чем сопоставление по строке, но попробовал несколько вещей (например, classOf[String]) и не могу найти то, что работает.

Для контекста, getOption (в суперклассе, который мы пытаемся переопределить) получает значение Option из объекта JV4ue AST json4s

def getOption[T: TypeTag: ClassTag](path: String): Option[T] = Try(getJValue(path).extract[T]).toOption

def getJValue(path: String): JValue = {
  path.split('.').foldLeft(value)((a, b) => a \ b) match {
    case JNull => JNothing
    case j     => j
  }
}

Идея состоит в том, что я хочу подправить его так, чтобы только для строковых типов этого метода мы хотели обрабатывать пустые строки особым образом.

2 ответа

Решение

Вы можете сделать прямые тесты на равенство между ClassTagвот так:

override def getOption[T: TypeTag: ClassTag](path: String): Option[T] = {
  // not required, just nicer to write classTag[T] vs. implicitly[ClassTag[T]]
  import reflect.classTag
  classTag[T] match {
    case strTag if strTag == classTag[String] => HandleBlank(super.getOption[String](path)).asInstanceOf[Option[T]]
    case _ => super.getOption[T](path)
  }
}

Один из распространенных приемов - поместить значение, с которым вы хотите сравнить, в локальную переменную или поле:

import scala.reflect.classTag

val StringTag = classTag[String]

override def getOption[T: TypeTag: ClassTag](path: String): Option[T] = {
  classTag[T] match {
    case StringTag => ...
    case _ => ...
  }
}

Обратите внимание, что имя должно начинаться с заглавной буквы, в противном случае case stringTag просто свяжет новую переменную (хотя вы можете окружить stringTag с `чтобы исправить это).

Другие вопросы по тегам