您的位置:首页 > 编程语言

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

2016-07-11 08:42 337 查看


chapter 2 控制结构和函数

标签:快学scala


一、笔记

scala的if/else表达式有值,这个值就是跟在if或else之后的表达式的值。所以可以赋值给变量。每个表达式都有一个类型。

val s = if(x>0) 1 else -1

[/code]

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.

[/code]

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)

[/code]

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

[/code]

lazy值的初始化被延迟,直到我们首次对它取值。

scala> lazy val words = scala.io.Source.fromFile("/root/scala/plus.java").mkString

words: String = <lazy>

scala> words

res2: String = .....

[/code]

异常

和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>)

[/code]

第一个分支类型是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

[/code]

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

scala> val x = {}

x: Unit = ()

[/code]

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 = ()

[/code]

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

[/code]

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

[/code]

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

[/code]

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

[/code]

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

[/code]

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

[/code]

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)

}

}

[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: