Используя scala, как мне сравнить два типа классов, когда в конце каждого из них есть $?

#scala #apache-spark

#scala #apache-spark

Вопрос:

Я пытаюсь сравнить тип класса запроса SparkSQL.

 scala> val plan = spark.sessionState.sqlParser.parsePlan("create table some_table as select 1")
scala> val childClass = plan.children.map(_.getClass).toList(0)

Class[_ <: org.apache.spark.sql.catalyst.plans.logical.LogicalPlan] = class org.apache.spark.sql.catalyst.plans.logical.Project
  

Однако, похоже, что это тот тип, который я получаю class org.apache.spark.sql.catalyst.plans.logical.Project , когда сравниваю это с помощью false . ……… isInstanceOf

 scala> childClass.isInstanceOf[org.apache.spark.sql.catalyst.plans.logical.Project]
                                                                                                                                           ^
res9: Boolean = false
  

Я думаю, проблема здесь в том, как компилируется класс org.apache.spark.sql.catalyst.plans.logical.Project .

 scala> org.apache.spark.sql.catalyst.plans.logical.Project.getClass
res21: Class[_ <: org.apache.spark.sql.catalyst.plans.logical.Project.type] = class org.apache.spark.sql.catalyst.plans.logical.Project$
  

$ Знак в конце вызывает проблемы. Однако, если я это сделаю childClass.getName и сравню строку с классом, я получу true но я не думаю, что это хороший способ сравнения классов здесь.

Это скорее вопрос scala, чем вопрос Spark, и проблема кажется тривиальной, но я, похоже, не могу понять, как сравнить тип класса, не сравнивая само имя необработанной строки.

Ответ №1:

org.apache.spark.sql.catalyst.plans.logical.Project.getClass вызывает getClass метод сопутствующего объекта для org.apache.spark.sql.catalyst.plans.logical.Project , который является одноэлементным экземпляром класса org.apache.spark.sql.catalyst.plans.logical.Project$ (в данном случае, просмотр кода Spark показывает, что это case class с синтетическим сопутствующим объектом).

Вы можете получить объект класса для org.apache.spark.sql.catalyst.plans.logical.Project с помощью:

 classOf[org.apache.spark.sql.catalyst.plans.logical.Project]
  

т. е.

 childClass.getClass == classOf[org.apache.spark.sql.catalyst.plans.logical.Project]
  

должно быть true.

Комментарии:

1. Спасибо за четкое объяснение, Леви, действительно помогло мне понять логику, стоящую за этим.

2. Я все еще немного сбит с толку, хотя я не вижу сопутствующего объекта для org.apache.spark.sql.catalyst.plans.logical.Project в коде spark. Я вижу только класс case. Как вы пришли к выводу, что getClass это относится к сопутствующему объекту?

3. Это case class , поэтому компилятор Scala синтезирует сопутствующий объект (в основном для apply метода (для построения объекта как функции)).