快学scala 第二章 读书笔记及习题答案代码

chapter 2 控制结构和函数

标签:快学scala


一、笔记

  1. scala的if/else表达式有值,这个值就是跟在if或else之后的表达式的值。所以可以赋值给变量。每个表达式都有一个类型。
 
 
  1. val s = if(x>0) 1 else -1

if (x>0) "positive" else -1 
这个表达式类型是两个分支类型的公共超类型,第一个是java.lang.String,另一个是Int,分支超类型是Any。 
if (x>0) 1 等同于 if(x>0) 1 else () 
()表示一个无用的占位符,Unit类型比作为java中的void类型。 
所以,不能出现 x=y=1的操作,y=1的值是(),不能将Unit类型的值赋值给x。 
2. 除了print和println,scala还有一个C风格的格式化字符串函数printf

 
 
  1. scala> printf("Hello, %s! You are %d years old.\n", "Josh", 42)
  2. Hello, Josh! You are 42 years old.
  1. scala中没有break和continue语句来退出循环。 
    变量<-表达式 这一形式提供多个生成器,分号隔开。
 
 
  1. scala> for(i <- 1 to 3; j <- 1 to 3)print((10*i+j)+" ")
  2. 11 12 13 21 22 23 31 32 33
  3. //每个生成器都可以带一个守卫,以if开头的Boolean表达式
  4. scala> for(i <- 1 to 3; j <- 1 to 3 if i!= j)print((10*i+j)+" ")
  5. 12 13 21 23 31 32
  6. scala> for(i <- 1 to 3; from = 4-i; j<- from to 3)print((10*i+j)+" ")
  7. 13 22 23 31 32 33
  8. //for循环以yield开始,每次迭代生成集合的一个值。
  9. scala> for(i <-1 to 10) yield i%3
  10. res25: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 0, 1, 2, 0, 1, 2, 0, 1)

for推导式生成的集合与它的第一个生成器是类型兼容的。 
4. 函数 
只要函数不是递归的,就不需要指定返回值类型。scala通过=右侧表达式推测类型。最后一个表达式值就是函数返回值。 
变长参数例子:

 
 
  1. scala> def sum(args: Int*)={
  2. | var result =0
  3. | for(arg <- args) result += arg
  4. | result
  5. | }
  6. sum: (args: Int*)Int
  7. scala> val s = sum(1,4,9,16,25) //函数得到的类型是一个Seq的参数
  8. s: Int = 55
  9. scala> val s = sum(1 to 5) //报错
  10. <console>:9: error: type mismatch;
  11. found : scala.collection.immutable.Range.Inclusive
  12. required: Int
  13. val s = sum(1 to 5)
  14. ^
  15. scala> val s = sum(1 to 5:_*) //追加 :_*
  16. s: Int = 15
  17. //递归定义
  18. scala> def recursiveSum(args:Int*): Int={
  19. | if(args.length == 0) 0
  20. | else args.head + re
  21. | else args.head + recursiveSum(args.tail:_*)
  22. | } //head是首元素,tail是所有其他元素的序列
  23. recursiveSum: (args: Int*)Int
  1. lazy值的初始化被延迟,直到我们首次对它取值。
 
 
  1. scala> lazy val words = scala.io.Source.fromFile("/root/scala/plus.java").mkString
  2. words: String = <lazy>
  3. scala> words
  4. res2: String = .....
  1. 异常 
    和java一样,抛出的异常的对象必须是java.lang.Throwable的子类,但scala不用声明函数或方法可能会抛出异常。
 
 
  1. scala> val x = -1
  2. x: Int = -1
  3. scala> if(x >=0) {sqrt(x)
  4. | }else throw new IllegalArgumentException("x should not be negative")
  5. java.lang.IllegalArgumentException: x should not be negative
  6. at .<init>(<console>:16)
  7. at .<clinit>(<console>)
  8. at .<init>(<console>:7)
  9. at .<clinit>(<console>)
  10. at $print(<console>)

第一个分支类型是Double,第二个分支类型是Nothing。

二、习题答案

2.1 一个数字如果为正数,则它的signum为1;如果是负数,则signum为-1;如果为0,则signum为0.编写一个函数来计算这个值。

 
 
  1. scala> def sigNum(num: Int):Int={
  2. | if(num >0) 1 else if(num < 0) -1 else 0
  3. | }
  4. sigNum: (num: Int)Int
  5. scala> println(sigNum(1))
  6. 1

2.2 一个空的块表达式{}的值是什么?类型是什么?

 
 
  1. scala> val x = {}
  2. x: Unit = ()

2.3 指出在Scala中何种情况下赋值语句x=y=1是合法的。(提示:给x找个合适的类型定义)

 
 
  1. scala> var x = {}
  2. x: Unit = ()
  3. scala> var y =1
  4. y: Int = 1
  5. scala> x = y =1
  6. x: Unit = ()

2.4 针对下列Java循环编写一个Scala版本: 
for(int i=10;i>=0;i--) System.out.println(i);

 
 
  1. scala> for(i <- 0 to 10 reverse)println(i)
  2. warning: there were 1 feature warning(s); re-run with -feature for details
  3. 10
  4. 9
  5. 8
  6. 7
  7. 6
  8. 5
  9. 4
  10. 3
  11. 2
  12. 1
  13. 0

2.5 编写一个过程countdown(n:Int),打印从n到0的数字。

 
 
  1. scala> def countdown(n: Int)={
  2. | for( i <- 0 to n reverse) println(i)
  3. | }
  4. warning: there were 1 feature warning(s); re-run with -feature for details
  5. countdown: (n: Int)Unit
  6. scala> countdown(3)
  7. 3
  8. 2
  9. 1
  10. 0

2.6 编写一个for循环,计算字符串中所有字母的Unicode代码的乘积。举例来说,”Hello”中所有字符串的乘积为9415087488L

 
 
  1. scala> def charMultiply(str: String): Long={
  2. | var result =1
  3. | for(i <- str) result *= i
  4. | result
  5. | }
  6. charMultiply: (str: String)Long
  7. scala> charMultiply("Hello")
  8. res18: Long = 825152896

2.7 同样是解决前一个练习的问题,但这次不使用循环。(提示:在Scaladoc中查看StringOps)

 
 
  1. scala> def charMultiply(str :String):Long = {
  2. | var result:Long =1
  3. | str.foreach(ch => {result *= ch.toLong})
  4. | result
  5. | }
  6. charMultiply: (str: String)Long
  7. scala> charMultiply("Hello")
  8. res19: Long = 9415087488

2.8 编写一个函数product(s:String),计算前面习题中提到的乘积。

 
 
  1. scala> def product(str: String): Long={
  2. | var result:Long =1
  3. | str.foreach(result *= _.toLong)
  4. | result
  5. | }
  6. product: (str: String)Long
  7. scala> product("Hello")
  8. res0: Long = 9415087488

2.9 把前一个练习中的函数改成递归函数。

 
 
  1. scala> def product(str: String): Long={
  2. | var result:Long =0
  3. | if(str.length == 1)
  4. | result = str.head.toLong
  5. | else
  6. | result = str.head.toLong * product(str.tail)
  7. | result
  8. | }
  9. product: (str: String)Long
  10. scala> product("Hello")
  11. res1: Long = 9415087488

2.10 编写函数计算x^n, 其中n为整数。使用如下的递归定义: 
x^n = y^2,如果n是正偶数的话,y=x^(n/2) 
x^n = x*x^(n-1), 如果n是正奇数。 
x^0 = 1 
x^n = 1/x^(-n), 如果n是负数。 
不使用return语句。

 
 
  1. import math._
  2. object test{
  3. def main(args: Array[String]):Unit={
  4. println(power(1.4, 5))
  5. }
  6. def power(x: Double, n:Int): Double ={
  7. if(n==0) 1
  8. else if (n>0 && n %2 !=0) x*power(x, n-1)
  9. else if(n>0 && n%2 ==0) pow(power(x, n/2),2)
  10. else 1/power(x, -n)
  11. }
  12. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值