这篇文章总结一下我在学习spark sql源码时,曾经纠结过的一些scala语法。
在精读sparksql源码之前,我们需要有一定的scala语法知识,来保证能够看懂sparksql代码,并上手调试。
有同学不会scala,就会有一种恐惧心理,其实不用怕,因为我一开始也不会scala代码。我是边看sparksql源码,边学习语法,看到不懂的地方,就从网上搜索相关的语法,把相关语法弄懂了之后,再写个scala的测试类,实现一个案例执行一下,加深理解,然后,再继续读源码。
到现在,我已经能熟练的用scala写一段了,虽然写不是很规范,但是看懂、调试、修改代码完全没有问题。 并且边用边学这种方式效率很高,这么说,并不是鼓励大家都用我这种方式,如果有条件,还是从网上找一些scala的基础视频看看,提前学一学,肯定会更好~
1、偏函数
当在调用一个函数时,把这个函数应用到参数中。如果传递所有预期的参数,则表示您已完全应用它。如果只传递几个参数并不是全部参数,那么将返回部分应用的函数。这样就可以方便地绑定一些参数,其余的参数可稍后填写补上。
trait PartialFunction[-A, +B] extends (A => B) { self =>
import PartialFunction._
def isDefinedAt(x: A): Boolean
def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] =
new OrElse[A1, B1] (this, that)
override def andThen[C](k: B => C): PartialFunction[A, C] =
new AndThen[A, B, C] (this, k)
def lift: A => Option[B] = new Lifted(this)
def applyOrElse[A1 <: A, B1 >: B](x: A1, default: A1 => B1): B1 =
if (isDefinedAt(x)) apply(x) else default(x)
def runWith[U](action: B => U): A => Boolean = { x =>
val z = applyOrElse(x, checkFallback[B])
if (!fallbackOccurred(z)) { action(z); true } else false
}
}
可以说,sparksql的源码中,到处都是偏函数。
比如:生成解析后逻辑执行计划中的解析器、优化逻辑执行计划的优化器等。
逻辑执行计划解析器ResolveRelations(解析表和视图):