快学Scala第二章

2.1 条件表达式·

if/else表达式有值,这个值就是跟在if或else之后的表达式的值。如:

if (x > 0) 1 else -1

因此可以将if/else表达式的值赋值给变量:

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

这与以下语句的效果是一样的:

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

第一种写法可以用来初始化一个val,第二种写法只能初始化var。

在scala中,每个表达式都有一个类型。

if (x > 0) "positive" else -1

上述if分支,一个是java.lang.String,而另一个分支是Int。它们的公共超类型叫做Any。

2.2 语句终止

省略分号可以。使用分号也行。注意的是在命令行模式下一行的结束问题。

2.3 块表达还是和赋值

在Scala中,{}块包含一系列表达式,其结果也是一个表达式。块最后一个表达式的值就是块的值。

val distance = { val dx = x - x0; val dy = y - y0; sqrt(dx*dx + dy * dy)}

Scala中的Unit类型等同于Java中的void,这个类型只有一个值,写作()。
赋值动作本身是没有值得,更严格的说,它们的值是Unit类型的。也就是

n=-1

这个赋值语句除了使n为-1之外,语句本省也有一个值,这个是是Unit。所以下面的连续赋值不能实现与Java中相同的目的:

x = y = -1

与= -1的值是()。

2.4 输入和输出

print
println
printf("Hello, %s ! You are %d years old.\n","Fred",42)

还有一些其他函数

readLine
readInt
readDouble
readByte
readShort
readLong
readFloat
readBoolean
readChar

2.5 循环

while (n > 0) {
	r = r * n
	n -= 1
}

scala的for循环有所不同

for (i <- 1 to n)
	r = r * i

1 to n 产生一个Range,让i去遍历这个Range中的所有元素
遍历字符串或者数组时,你通常要使用0到n-1的区间。此时可以使用until方法。而不是to方法。util方法返回一个并不包含上限的区间。
break

import scala.util.control.Breaks._
breakable {
	for (...) {
		if (...) break;
	}
}

2.6 高级for循环和for推导式

可以以 变量 <- 表达式的形式提供多个生成器:

for (i <- 1 to 3; j <- 1 to 3) print ((10 * i + j) + " ")

每个生成器都可以带一个守卫,以if开头的Boolean表达式

for (i <- 1 to 3; j <- 1 to 3 if i != j ) print ((10 * i + j) + " ")

你可以使用任意多的定义,引入可以在循环中使用的变量:

for (i <- 1 to 3; from = 4 - i; j <- from to 3) print ((10 * i + j) + " ")

如果for循环体以yield开始,则该循环会构造出一个集合,每次迭代生成集合中的一个值:

for (i <- 1 to 10) yield i % 3

这个就是for推导式,它生成的集合与它的第一个生成器是类型兼容的。

for (c <- "Hello"; i <- 0 to 1) yield (c + i).toChar

2.7 函数

一般地,我们不用写函数的返回值类型

def fac(n: Int) = {
	var r = 1
	for (i <- 1 to n) r = r * i
	r
}

上述函数的返回值,是表达式块的最后一个r的值。可以看到,我们也不用写return语句。
但是对于递归函数,我们需要指定返回值的类型:

def fac(n: Int): Int = if (n <= 0) 1 else n * fac(n - 1)

如果没有返回类型,Scala编译器无法校验n * fac(n-1)的类型是Int。

2.8 默认参数和带名参数

调用某些函数时,并不显式地给出所有的参数值,对于这些函数我们可以使用默认参数。

def decorate (str: String, left: String = "[" , right: String = "]") = 
left + str + right

调用函数时可以提供带名的参数。

2.9 变长参数

def sum(args: Int*) = {
	var result = 0
	for (arg <- args) result += arg
	result
}

可以使用任意多的参数来调用它

def recursiveSum(args: Int*): Int = {
	if (args.length == 0) 0
	else args.head + recursiveSum(args.tail:_*)
}

2.10 过程

过程是定义函数时,不需要返回值的,也就没有函数名后面的等于号

def box(s: String) {
	var border = "-" * s.length + "--\n"
	println(border +"|" + s + "|\n" + border)
}

其实,过程返回的是一个Unit类型,:

def box(s: String) : Unit = {
...
}

2.11 懒值

当val被声明为lazy时,它的初始化将被推迟,直到我们首次对它取值。

lazy val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString

注意下面三种取值的时间

val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString
//在words被定义时即被取值
lazy val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString
//在words被首次使用时即被取值
def words  = scala.io.Source.fromFile("/usr/share/dict/words").mkString
//在每次words被使用时取值

2.12 异常

scala的异常机制和Java或C++一样。当你抛出异常时,比如:

throw new Illega;ArgumentException("x should not be negative")

当前的运算被终止,运行时系统查找可以接受IllegalArgumentException的异常处理器。

在scala中,"受检"异常不支持。受检查的异常在编译器被检查。在java中,如果你的方法可能会抛出IOException,你必须做出声明。

try {
	procerss(new URL("http://horstman.com/fred-tiny.gid"))
} catch {
	case _: MalformedURLException => println("Bad URL: " + url)
	case ex: IOException => ex.printStackTrace()
}

练习

def (x : Integer) = {
	if (x > 0) 
		x.sigsum = 1
	else if (x < 0)
	    x.sigsuim = -1
	else
		x.sigsum = 0
}
for (i <- 0 to 10; j = 10 -i ) println(j)
def countdown(x : Int) {
	for (i <- 0 to n)
		println(n - i)
}
var sum = 1L
for (c <- "Hello") sum *= c.toLong
println(sum)
def product(s: String) : Long = {
	var sum = 1L
	for (c <- s) 
		sum = sum * c.toLong
	sum
}
def product(s: String) : Long = {
	if (s.size == 1)
		return s(0).toLong
	else
		return s.head.toLong * product(s.tail) 
}
def calculate(x: Int, n: Int) : Long = {
	if (n == 0) 1
	else if (n < 0) 1 / calculate(x, -n)
	else if( n % 2 == 0) calculate(x,n/2) * calculate(x,n/2)
	else x * calculate(x,n-1)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值