最近,我正在阅读火花的来源。当到达“ org.apache.spark.deploy.SparkSubmit”的类时,我对关键字“ self”和运算符“ =>”感到困惑。有人可以为我解释一下吗?
override def main(args: Array[String]): Unit = {
val submit = new SparkSubmit() {
self =>
override protected def parseArguments(args: Array[String]): SparkSubmitArguments = {
new SparkSubmitArguments(args) {
override protected def logInfo(msg: => String): Unit = self.logInfo(msg)
override protected def logWarning(msg: => String): Unit = self.logWarning(msg)
}
}
override protected def logInfo(msg: => String): Unit = printMessage(msg)
override protected def logWarning(msg: => String): Unit = printMessage(s"Warning: $msg")
override def doSubmit(args: Array[String]): Unit = {
try {
super.doSubmit(args)
} catch {
case e: SparkUserAppException =>
exitFn(e.exitCode)
case e: SparkException =>
printErrorAndExit(e.getMessage())
}
}
}
顺便说一句:这个问题与“重复的问题”完全不同。尽管这两者是非常相同的,但我要问的是关于“新类”关键字附近的“自我=>”,而不是在scala的类定义中与“重复的名称”相似的“重复”。这不是一个相同的问题
答案 0 :(得分:1)
声明
self =>
被称为“自我类型注释”,它创建一个名为self
的值,该值引用正在构造的类的实例。可以在该类的this
值不可用的地方使用。特别是,它可以在嵌套类内部使用,其中this
指的是嵌套类,而对外部类的引用不会自动可用。
在您的情况下,此处使用self
:
new SparkSubmitArguments(args) {
override protected def logInfo(msg: => String): Unit = self.logInfo(msg)
override protected def logWarning(msg: => String): Unit = self.logWarning(msg)
}
这使得SparkSubmitArguments
的新实例使用外部包含类的logInfo
和logWaringing
方法。在代码的这一点上,您不能使用this
,因为它将引用内部类,而不是外部类。 (如果您确实使用this
,则会出现无限循环)
答案 1 :(得分:0)
它是this
的别名。这样做是为了消除内部类中的自引用。
在内部类的范围内使用this
时,它引用内部类的实例。如果需要引用外部类,则需要一个别名:
class Foo { self =>
val x = 1
new AnyRef {
val x = 2
println(this.x) // 2
println(self.x) // 1
}
}