Spark
版本 1.3.0 。
SQLContext.scala
(https://github.com/apache/spark/blob/master/sql/core/src/main/scala/org/apache/spark/sql/SQLContext.scala)的源代码:
@transient
protected[sql] val ddlParser = new DDLParser(sqlParser.apply(_))
@transient
protected[sql] val sqlParser = {
val fallback = new catalyst.SqlParser
new SparkSQLParser(fallback(_))
}
protected[sql] def parseSql(sql: String): LogicalPlan = {
ddlParser(sql, false).getOrElse(sqlParser(sql))
}
我无法理解上面的代码。
sqlParser.apply(_)
如何运作?地球上的(_)是什么? DDLParser 的构造函数需要参数parseQuery: String => LogicalPlan
,但sqlParser.apply
的返回类型为LogicalPlan
。
fallback(_)
也是apply
来电,(_)如何运作?答案 0 :(得分:1)
这种情况下的下划线表示部分函数应用程序,这是将方法类型转换为函数类型的一种方法。因此,当您编写sqlParser.apply(_)
时,它等同于x => sqlParser.apply(x)
。由于DDLParser
构造函数需要类型为String => LogicalPlan
的参数,而sqlParser.apply
返回LogicalPlan
,编译器可以推断x
这里实际上是{{1}因此String
属于sqlParser.apply(_)
类型。
这里有很多选择。在大多数情况下,以下内容相同:
String => LogicalPlan
您可以阅读有关方法类型和函数类型here之间差异的更多信息。
将方法类型转换为函数类型的另一种密切相关的方法称为 eta expansion ,它在某些上下文中可互换使用。阅读部分函数应用程序,eta扩展以及Scala here中下划线的所有其他用法。