1. apply语法
FileShuffleBlockManager中定义的类ShuffleFileGroup,定义:
private class ShuffleFileGroup(val shuffleId: Int, val fileId: Int, val files: Array[File]) { ... def apply(bucketId: Int) = files(bucketId) ... }
那么当我们新建了ShuffleFileGroup对象后,
val fileGroup = new ShuffleFileGroup(shuffleId, fileId, files)
执行如下如下操作 val file = fileGroup(0),那么它自动调用ShuffleFileGroup类的apply方法,这里返回的是files这个File数组的第一个文件
Scala allows classes to define a special function named apply that is called when we treat an object as if it were a function, so head(5) is the same thing as head.apply(5). 这里head是个Array数组对象
In Scala, apply methods have some special syntactic sugar that allows us to call them without having to type them out explicitly; for example, these two lines do exactly the same thing:
val nastats = NAStatCounter.apply(17.29)
val nastats = NAStatCounter(17.29)
NAStatCounter这里是NAStatCounter类的伴生对象,在半生对象上调用apply方法,可以用于创建类对象
2.二维数组
代码来自于DiskBlockManager.scala
fill操作是产生一个长度为第一个参数的数组,同时每个元素使用第二个参数进行填充,这里第二个参数是个数组,因此这样就定义了一个二维数组
private val subDirs = Array.fill(localDirs.length)(new Array[File](subDirsPerLocalDir))
二维数组的两个维度分别用()()表示,这跟Java的二维数据a[0][0]道理一样,只不过Scala使用a(0)(0)来对于第一个元素
var subDir = subDirs(dirId)(subDirId)
3. for嵌套循环
忘记了在Spark的什么地方看到的这个语法现象,在scala终端上试了下才发现原来是嵌套循环
scala> val a1 = List(1,2,3) a1: List[Int] = List(1, 2, 3) scala> val a2 = List(4,5,6) a2: List[Int] = List(4, 5, 6)
scala> for(s1 <- a1; s2 <- a2) {println("s1=" + s1 + ",s2=" + s2)} s1=1,s2=4 s1=1,s2=5 s1=1,s2=6 s1=2,s2=4 s1=2,s2=5 s1=2,s2=6 s1=3,s2=4 s1=3,s2=5 s1=3,s2=6
可见这是个循环遍历a1和a2的操作,同时由输出结果可以看到,s1<-a1是外层循环,s2<-a2是内层循环