chapter 2 控制结构和函数
标签:快学scala
一、笔记
- scala的if/else表达式有值,这个值就是跟在if或else之后的表达式的值。所以可以赋值给变量。每个表达式都有一个类型。
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
scala> printf("Hello, %s! You are %d years old.\n", "Josh", 42)
Hello, Josh! You are 42 years old.
- scala中没有break和continue语句来退出循环。
变量<-表达式 这一形式提供多个生成器,分号隔开。
scala> for(i <- 1 to 3; j <- 1 to 3)print((10*i+j)+" ")
11 12 13 21 22 23 31 32 33
//每个生成器都可以带一个守卫,以if开头的Boolean表达式
scala> for(i <- 1 to 3; j <- 1 to 3 if i!= j)print((10*i+j)+" ")
12 13 21 23 31 32
scala> for(i <- 1 to 3; from = 4-i; j<- from to 3)print((10*i+j)+" ")
13 22 23 31 32 33
//for循环以yield开始,每次迭代生成集合的一个值。
scala> for(i <-1 to 10) yield i%3
res25: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 0, 1, 2, 0, 1, 2, 0, 1)
for推导式生成的集合与它的第一个生成器是类型兼容的。
4. 函数
只要函数不是递归的,就不需要指定返回值类型。scala通过=右侧表达式推测类型。最后一个表达式值就是函数返回值。
变长参数例子:
scala> def sum(args: Int*)={
| var result =0
| for(arg <- args) result += arg
| result
| }
sum: (args: Int*)Int
scala> val s = sum(1,4,9,16,25) //函数得到的类型是一个Seq的参数
s: Int = 55
scala> val s = sum(1 to 5) //报错
<console>:9: error: type mismatch;
found : scala.collection.immutable.Range.Inclusive
required: Int
val s = sum(1 to 5)
^
scala> val s = sum(1 to 5:_*) //追加 :_*
s: Int = 15
//递归定义
scala> def recursiveSum(args:Int*): Int={
| if(args.length == 0) 0
| else args.head + re
| else args.head + recursiveSum(args.tail:_*)
| } //head是首元素,tail是所有其他元素的序列
recursiveSum: (args: Int*)Int
- lazy值的初始化被延迟,直到我们首次对它取值。
scala> lazy val words = scala.io.Source.fromFile("/root/scala/plus.java").mkString
words: String = <lazy>
scala> words
res2: String = .....
- 异常
和java一样,抛出的异常的对象必须是java.lang.Throwable的子类,但scala不用声明函数或方法可能会抛出异常。
scala> val x = -1
x: Int = -1
scala> if(x >=0) {sqrt(x)
| }else throw new IllegalArgumentException("x should not be negative")
java.lang.IllegalArgumentException: x should not be negative
at .<init>(<console>:16)
at .<clinit>(<console>)
at .<init>(<console>:7)
at .<clinit>(<console>)
at $print(<console>)
第一个分支类型是Double,第二个分支类型是Nothing。
二、习题答案
2.1 一个数字如果为正数,则它的signum为1;如果是负数,则signum为-1;如果为0,则signum为0.编写一个函数来计算这个值。
scala> def sigNum(num: Int):Int={
| if(num >0) 1 else if(num < 0) -1 else 0
| }
sigNum: (num: Int)Int
scala> println(sigNum(1))
1
2.2 一个空的块表达式{}的值是什么?类型是什么?
scala> val x = {}
x: Unit = ()
2.3 指出在Scala中何种情况下赋值语句x=y=1是合法的。(提示:给x找个合适的类型定义)
scala> var x = {}
x: Unit = ()
scala> var y =1
y: Int = 1
scala> x = y =1
x: Unit = ()
2.4 针对下列Java循环编写一个Scala版本:
for(int i=10;i>=0;i--) System.out.println(i);
scala> for(i <- 0 to 10 reverse)println(i)
warning: there were 1 feature warning(s); re-run with -feature for details
10
9
8
7
6
5
4
3
2
1
0
2.5 编写一个过程countdown(n:Int),打印从n到0的数字。
scala> def countdown(n: Int)={
| for( i <- 0 to n reverse) println(i)
| }
warning: there were 1 feature warning(s); re-run with -feature for details
countdown: (n: Int)Unit
scala> countdown(3)
3
2
1
0
2.6 编写一个for循环,计算字符串中所有字母的Unicode代码的乘积。举例来说,”Hello”中所有字符串的乘积为9415087488L
scala> def charMultiply(str: String): Long={
| var result =1
| for(i <- str) result *= i
| result
| }
charMultiply: (str: String)Long
scala> charMultiply("Hello")
res18: Long = 825152896
2.7 同样是解决前一个练习的问题,但这次不使用循环。(提示:在Scaladoc中查看StringOps)
scala> def charMultiply(str :String):Long = {
| var result:Long =1
| str.foreach(ch => {result *= ch.toLong})
| result
| }
charMultiply: (str: String)Long
scala> charMultiply("Hello")
res19: Long = 9415087488
2.8 编写一个函数product(s:String),计算前面习题中提到的乘积。
scala> def product(str: String): Long={
| var result:Long =1
| str.foreach(result *= _.toLong)
| result
| }
product: (str: String)Long
scala> product("Hello")
res0: Long = 9415087488
2.9 把前一个练习中的函数改成递归函数。
scala> def product(str: String): Long={
| var result:Long =0
| if(str.length == 1)
| result = str.head.toLong
| else
| result = str.head.toLong * product(str.tail)
| result
| }
product: (str: String)Long
scala> product("Hello")
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语句。
import math._
object test{
def main(args: Array[String]):Unit={
println(power(1.4, 5))
}
def power(x: Double, n:Int): Double ={
if(n==0) 1
else if (n>0 && n %2 !=0) x*power(x, n-1)
else if(n>0 && n%2 ==0) pow(power(x, n/2),2)
else 1/power(x, -n)
}
}