Получить явный тип универсального параметра во время выполнения в Scala - PullRequest
2 голосов
/ 25 сентября 2019

Примечание - этот пост ссылается на Spark, но не обязательно - он может применяться ко всему, что требует параметр типа (например, case class MyThing[T](t:T))

Я пытаюсь определить, что такое класс времени выполненияимеет общий параметр, особенно в наборе данных, чтобы выдать полезное сообщение об ошибке, я пытаюсь сделать что-то вроде:

def killIfEmpty[T](ds:Dataset[T])(implicit sparkSession:SparkSession):Unit = {
if (ds.head(1).isEmpty) {
  throw new Exception(s"Dataset[${
    ds.getClass.getSimpleName
  }] had zero rows.")
}

}

Но, к сожалению, это нене могу показать ничего полезного, вызывая

val spark:SparkSession = ???
val emptyDs:Dataset[String] = ???
killIfEmpty[Dataset[String]](emptyDs)

Я ожидаю, что это напечатает сообщение, которое говорит:

Набор данных [String] содержит ноль строк.

Но что происходит, это приводит к:

Набор данных [Набор данных] содержит ноль строк.

Кто-нибудь знает, как получить фактическое имя класса изуниверсальный параметр?

1 Ответ

3 голосов
/ 26 сентября 2019

Понятно, мне нужно работать с TypeTag

import scala.reflect.runtime.universe._

def killIfEmpty[T : TypeTag](ds:Dataset[T])(implicit sparkSession:SparkSession):Unit = {
    if (ds.head(1).isEmpty) {
      throw new Exception(s"Dataset[${
        datasetBaseClassName(typeTag[T])
      }] had zero rows.")
    }
  }

  private def datasetBaseClassName[T : TypeTag]: String = {
    typeOf[T].typeSymbol.name.toString
  }

Предоставление контекстного ограничения [T : TypeTag] в объявлении метода позволяет мне вызывать эти функции без явного указания тега.См. Документ границы контекста , чтобы узнать больше.

Я думаю, что есть способ сделать это без определения того же контекста, привязанного к общедоступной функции killIfEmpty, но я неуверен - я открыт для исправления!

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