在Apache Spark的Scala API中,使用单引号和$“”表示法之间有区别吗?

时间:2018-12-03 17:38:57

标签: scala apache-spark syntax

在引用列时(在这种情况下,在select语句中),我注意到两种不同的符号样式。两者在功能上有区别吗?

val df = spark.read.table("mytable").select('column1,'column2)

vs。

val df = spark.read.table("mytable").select($"column1",$"column2")

我找不到任何能真正解释差异或是否有标准的东西。

1 个答案:

答案 0 :(得分:1)

使用'column1,'column2$"column1",$"column2"中的任何一个时,返回值将是ColumnName(column1), ColumnName(column2),它恰好是Column()的子类,是预期的子类之一键入select。但是,它们的实现不同。

为了使用符号,导入import spark.implicits._要包含在应用程序中,其中sparkSparkSession对象。导入可确保以下隐式内容可用且在范围内。

通过Spark代码

   @Experimental
      object implicits extends SQLImplicits with Serializable {
        protected override def _sqlContext: SQLContext = SparkSession.this.sqlContext
      }

spark.implicits扩展了SQLImplicits

package org.apache.spark.sql

abstract class SQLImplicits extends LowPrioritySQLImplicits {

   ...

  /**
   * Converts $"col name" into a [[Column]].
   *
   * @since 2.0.0
   */
  implicit class StringToColumn(val sc: StringContext) {
    def $(args: Any*): ColumnName = {
      new ColumnName(sc.s(args: _*))
    }
  }

  ...

   /**
   * An implicit conversion that turns a Scala `Symbol` into a [[Column]].
   * @since 1.3.0
   */
  implicit def symbolToColumn(s: Symbol): ColumnName = new ColumnName(s.name)

}  

使用$column1时,将调用隐式类$中的StringToColumn方法,该方法将String转换为ColumnName实例。

'是scala符号。为了使用它,import spark.implicits._不是必需的。但是,要将Scala符号转换为Column,需要导入。使用此符号时,隐式方法symbolToColumn将被执行并返回一个ColumnName实例。请注意,'column1与Scala中的Symbol("column1")相同。

org.apache.spark.sql.Column.scala中,ColumnNameColumn的子类。因此从$'返回的对象可以在DataFrame / Dataset select方法中使用。

/**
 * A convenient class used for constructing schema.
 *
 * @since 1.3.0
 */
@InterfaceStability.Stable
class ColumnName(name: String) extends Column(name) {
    ...
}