一、for循环的进阶实战:
for 循环,2 to 3,是2~3,取值2、3,是个集合
Def main=(args:Array[String]):Unit{ For(i<- 2 to 3;j<- 3 to 5) Println((100*i+j)+“ ”)
也可在for循环中加入条件表达式(这是spark中最常见的形式,当然实际应用中条件是很复杂的):
For(i<- 2 to 3;j<- 3 to 5 if i!=j) Println((100*i+j)+“ ”) }
将2到3的集合每次循环赋值给i,将3到5的集合每次循环赋值给j,如果i!=j,就输出当i=2,j=3结果为203等
我们看到与Java不同的是,代码i,j都没有进行申明类型,它可以根据右侧类型元素自动进行类型推导。类型推导是Scala中非常强大的一个内容。
二、Function的进阶实战
(1)Function函数使用
函数有值是scala中的非常重要的特点,因为函数有值,函数执行必然有结果,所以函数可以作为函数的参数去传递,这是一个非常重要的结论,这个结论导致了函数式编程很多重要的技巧。
def Adds(x: Int) = x + 100
println("The result from a function is :" + Adds(2))
匿名函数-是函数最常见的一种形态,因为Scala里只关注函数怎么做,不关注它的名字
val adds = (x: Int) => x + 200
将匿名函数的值赋值给常量adds,=>是将接收的整数类型再去+200
println("The result from a val is " + adds(2))
函数返回值一般不指定,Scala会自动推导,但递归函数除外,因为递归函数并不知道上一次计算返回的什么样的结果
这里是求斐波那序列的值
def main(args: Array[String]): Unit = { def fac(n:Int): Int = if (n <= 0) 1 else n * fac(n - 1) //这里可以看到返回类型是int,如果不指定会报错 println("The result from a fac is : " + fac(5) )}
有默认参数的函数
//content参数被默认为I love Scala
def main(args: Array[String]): Unit = { def combine(content: String, left: String = "[", right: String = "]") = left + content + right println("The result from a combine is : " + combine("I love Scala", "#", "#"))}
参数可变的函数(通过*表示可以输入多个参数),即参数可变.这里将传入的参数累加,赋值给result
def main(args: Array[String]): Unit = {
def connected(args: Int*) = {
var result = 0
for(arg <- args) result += arg
result }
println("The result from a connected is : " + connected(1,2,3) )
println("The result from a connected is : " + connected(1,2,3,4,5) )
}
三、Lazy延迟加载和延迟执行
如果真实的路径下不存在test.txt, 使用 Source.fromFile()函数读取文件,就会报错抛出异常, 但是如果引用的变量或常量前加上 lazy,它只有在第一次被使用时,才被实例化,lazy会延迟执行。当发生错误,但没有立即被使用,程序还是OK,只有在被使用才会报错,懒加载的意义在于延迟执行,可以看到一个计算的更多步骤,优化的范围更大,优化的力度也更大。
例如我们在java中,一个错误就可能让我们的后边的工作无法进行,而延迟执行,可以放任这个错误,继续后边的工作,再从整体的逻辑里再去优化解决这个错误,会更好。
import scala.io.Source object Test { def main(args: Array[String]): Unit = {
lazy val file = Source.fromFile("e:\\test.txt")
println("Scala");
for (line <- file.getLines()) {
println(line);
} }}