Scala函数式程序设计原理 week1 Getting Started + Functions & Evaluation

求值策略

两种策略

Scala中有两种求值策略,一种叫做calll by name一种叫做call by value。两种策略会规约成相同的最终值,只要满足

  • 规约表达式由纯函数组成
  • 两者求值过程能够终止(不存在无限循环)

终止性质

当不满足终止条件时

  • 如果CBV能够终止,那么CBN也能够终止
  • 反之不成立
    Scala中通常使用call-by-name,如果函数参数的类型以=>开头,则表明使用call-by-name。
def constOne(x:Int,y:Int => Int) = 1

条件表达式

Scala中的if-else是表达式,由有值。每个表达式都有一个类型,表达式的类型是两个公共分支的超类型。
如果else部分缺失了,

if (x>0) 1

那么可能if语句没有输出值,解决办法是引入一个Unit类,写作()。等同于

if (x>0) 1 else ()

可以把()当作”无有用值”的占位符,将Unit当作void。(从技术上讲void没有值但是Unit有一个表示”无值”的值)

声明值和变量

val被定义时即被取值
lazy val在首次使用时取值
def在每一次被使用时取值

返回值类型

递归函数需要显式地指明返回值的类型,非递归函数的返回值类型是可选的。

块表达式

{}块包含一系列表达式,其结果也是一个表达式。块中最后一个表达式的值就是块的值。
在Scala中,赋值动作本身是没有值得,严格地说他们得值是Unit类型的,写作()
由于赋值语句的值是Unit类型,不要把他们串联在一起。

x = y = 1 //别这样做

可见性

块表达式内部的定义只能内部可见。内部的定义会遮蔽外部的同名定义。

分号和中缀运算符

Scala中,行尾的分号是可选的。
一行中有多个语句,每个语句用分号分隔。
当要多行表达式的时候,可以卸载括号内。

(someLongExp +somOtherExp)

或者可以在第一行写操作符,因为这告诉编译器表达式还未结束

someLongExp + 
someOtherExp

尾递归

如果一个函数在最后一步操作中调用自身,那么函数调用栈空间可以被重复使用。这叫做尾递归
尾递归是迭代过程
在Scala中,只有直接递归调用自身是可以被优化的。
使用@tailrec注解可以要求函数是尾巴递归的

@tailrec
def gcd(a: Int,b: Int): Int = ...

如果gcd的实现不是尾递归的,会报错。

参考资料

Scala函数式程序设计原理 week1
《快学Scala 第一版》

全部评论

相关推荐

明天不下雨了:兄弟你是我今天看到的最好看的简历(我说的是简历风格跟简历书写)把985 211再搞亮一点。投boss就说;您好,我华科(985)研二在读,本科211。对您的岗位很感兴趣,希望能获得一次投递机会。
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
2024-12-30 18:02
程序员牛肉:1.可以标记一下自己的学校是985,有一些hr可能没想到你这个院校是985的。 2.简历所呈现出来的能力还是有点差的,苍穹外卖+黑马点评。这在java技术域里面也就是刚学三四个月的样子,大厂现在招人少,小厂又更加希望你能直接过来干活。就你简历上呈现出来的能力,确实是有点难找,肉眼可见的不懂技术。 第一个项目中:简单的使用redis也算是亮点嘛?使用jwt,threadlocal也算是亮点?你不就是调了几个包嘛?Nginx作为服务器也能写出来,这不是前端的活嘛? 第二个项目中:分布式锁+mq消息队列+Lua队列。真没啥好问的。属于面试官看一眼就阳痿的简历,没有任何想提问的欲望。 我给你建议是好好的挖一挖这个项目吧,其实苍穹外卖和黑马点评这两个项目很不错了,只不过是太烂大街了导致面试官没啥问的兴趣,所以不太推荐写简历上。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务