每天学点Scala 1

Motivation:

1 Spark很多代码都是scala写的,不学习scala,看起来实在云里雾里

2 Actor和AKKA模型,向往已久,自己的产品里面也有使用这些,但还无缘一窥究竟。为学习AKKA做准备。




Scala的使用环境设置参考

https://class.coursera.org/progfun-004/wiki/ToolsSetup


1 REPL

read eval print loop, 其实就是控制台窗口,打开的方式有两种

i 在cmd中直接使用scala命令

ii在cmd中使用sbt console命令


2 Evaluation

1 表达式 evaluation

每天学点Scala 1_第1张图片

例子

每天学点Scala 1_第2张图片


2 函数 Evaluation

函数


Evaluation




例子

每天学点Scala 1_第3张图片


Substitution Model 




Termination

def loop:Int = loop

上面的这个函数就没法最终归结到一个value,是一个无限循环(因为这里是递归调用,所以要指明返回类型)


另外一种函数的Evaluation 模式

每天学点Scala 1_第4张图片


Call by Name 和 Call by Value

每天学点Scala 1_第5张图片

CBN通常意义上更容易terminate,相对于CBV,比如

def Xfun(x:Int, y:Int):Int = x

Xfun(3, loop)

上面的函数,CBN可以terminate,但是CBV却不可以。


Scala Evaluation Mode

Scala中默认使用CBV,虽然有的时候不会terminate,但是这种方式提供了很好的效率。有的时候需要显示的设置为CBN方式


def ConstantOne(X: Int, Y: => Int ) = 1


ConstantOne(2, loop) // 这里loop被设置为CBN,而且最终也不会用到,可以正常terminate。


3 条件判断

条件判断基本和Java兼容,因为毕竟scala是兼容Java的。

def abs(x: Int) = if x < 0 -x else x


val x = 3

val x = 3 + 3

val x = loop // 这里会造成无限循环,因为这里定义的时候,就会进行evaluate了,但是这样就导致了无限循环

def x = loop

val x = squre(3)


valu类型的是immutable的,而且最终的value是在定义一开始的位置就立刻进行evaluation的,val是典型的CBV,val在下面被引用的时候,直接饮用的是对应的值。



4 Square Root




每天学点Scala 1_第6张图片


这里,比较的时候绝对差,这样会造成,如果开放的是非常小的数值的话或者是非常大的数值,就会出现问题,

非常小:因为误差计算设置为0.001,有可能相对较大,比如给0.0000001开方。

非常大:因为计算机精度有限,比如1.01*10^60, 需要由63位的精度才能计算到可以停止计算的结果,但是精度有限,就造成了无限循环,计算不出结果。

递归:递归方法调用,需要指明返回值类型


block and lexical scoping



上图中,因为用大括号包住了内部的3个小函数,那么内部的函数对外就不可见了,同时最外层的参数x,对内是可见的,所以,不需要给每个函数显示的传递这个参数了

Semicolon

作为每行结束的标记,分号可以加也可以不加。默认每行自己动结束,可以用如下的方法,把一个句子写在多行。

每天学点Scala 1_第7张图片




Tail Recursion

最小公约数计算

def gcd(x:Int, y:Int) = {
    if x == 0 y
    else gcd(y, y/x)
}

最开始看有点看不懂,仔细想来,还是找到一些头绪
每天学点Scala 1_第8张图片

再看下面的例子,阶乘计算
每天学点Scala 1_第9张图片

比价下两个算法的计算过程,可以发现,上面GCD算法,计算过程,每步都不用存储很多中间变量,而阶乘算法,却要到最后才能得到结果,式子会越来越长,占用很多内存。

@tailrec
上面的annotation可以作为标记要求函数使用尾递归实现,否则报错

尾递归版本阶乘

def factorial(n:Int)={
def loop(acc:Int, n:Int) = {
if n==0 acc
else loop(acc*n, n-1)
}

loop(n)
}
这样就实现了尾递归版本的阶乘运算,节省了很多存储空间。

你可能感兴趣的:(每天学点Scala 1)