寒假学习日报(十)

  昨天晚上又熬夜了,今天整个人状态都很差。下午找了一下假期需要阅读的书籍,补上了一篇读书笔记。

  编程方面简单看了一下scala,因为要开始spark的学习了,为了能更好地掌握spark,我决定先接触一下scala,因为spark是用scala编写的。今天的日报仅仅对scala做一个介绍,因为并没有敲多少代码,大部分时间都用去看书和学习视频了。

  Scala主要特点是支持函数式编程,它可以嵌套调用java代码,可以被JVM执行。Scala中可以使用val,var,def三种关键字来命名,val是immutable类型,只能在初始化的时候赋值一次,var表示mutable类型,可以被赋值多次,def关键字声明是function value,同样是immutable类型,只有在使用时才会分配变量。变量定义如下(插入代码选项里没有scala,因此使用java格式进行插入):

val a = 1
var b = 2
def c = 3

  函数定义举例:

//int型参数的+1操作,无返回值。
def f(x: Int) = {x+1};
def f(x: Int) = x+1
def f(x: Int) = (x+1)

//不带参数,没有返回值的函数,通过o调用,直接输出
def o{println("Hello Scala")}

//带参数,类型为Unit,返回类型为Unit
def add(x: Unit):Unit={
println(x)
x
}

//匿名函数
(x: Int)=>x+1    //等价于{def f(x: Int) = x + 1; f _}

  高阶函数,函数参数可以为函数:

// 参数func为函数类型的变量,GaoJie为高阶函数,函数会把一个List中的元素按照func来做映射
def GaoJie(arr: List[Int], func: (Int) => Int): List[Int] = {
  arr.map(func)
}
Test(List(1,2,3), (x: Int) => x*x)

  Scala支持函数式编程,其中使用了非常多的递归,以阶乘代码举例:

def ff(n: Int): Int =
  if (n == 0) 1 else n * ff(n - 1)
/* 
函数的调用方式如下
ff(3)
if(3 == 0)1 else 3*ff(3 - 1)
3*ff(2)
3*(2*ff(1))
3*(2*(1*ff(0)))
3*(2*(1*(1*1)))
6
*/

  除了上述实现过程,还有另一种方式:尾递归

def ff(n: Int): Int = {
  @tailrec
  def ta(x: Int, res: Int): Int =
    if (x == 0) res
    else ta(x - 1 , res * x) 
    ta(n, 1)
}
// ff(3)结果是6
/*
函数的调用方式如下
ff(3)
ta(3,1)
if(3==0) 1 else ta(2,3*1)
if(2==0) 3 else ta(1,3*2)
if(1==0) 6 else ta(0,3*2*1)
if(0==0) 6 else ta(...)
return 6
*/

  尾递归过程中不需要保存之前调用的堆栈,因为结果(res)作为一个参数传递了下去,Scala编译器会对此做一个自动优化,避免过多的堆栈调用开销。

  柯里化(Currying):函数返回值依然为函数

def cur(x:Int): (Int)=>Int = {
  def squ(y:Int): Int = {
    y*y
  }
  x + squ(_)
}
// cur(1)(2)=5
// 等价于下面的实现方式
def cur(x:Int, y:Int): Int = {
    x + y*y
}

  以上是今天的全部学习内容。

原文地址:https://www.cnblogs.com/20183711PYD/p/14299280.html