1.基础部分
1.1 定义常量和变量
val xmax,ymax:Int=100
var greeting:String="Hello"
1.2 数值和操作符重载
数值操作符: +,-,*,/,%
逻辑操作符: & ,|, ^,>>,<<
自增操作: +=1
说明: ++ or -- 被去掉了
Int class 是immutable, 而++ 或者--方法将改变这个数值,
因此放在Int 类里是不合适的
1.3 调用函数和方法
方法一定是 class.methodname(parameters)
没有括号的方法 calss.methodname: 1:没有参数 2.不会修改object
函数则并不许要class,直接可以使用。例如min(3, Pi) 。
数字计算函数定义在 import scala.math._ 包中
1.4 apply 方法:
StringOps 类中方法 :
def apply(n: Int): Char
例如 “Hello”(4) 返回 "o"
companion object 的apply 方法 则会构造 一个 新的object
例如:BigInt("1234567890")
1.6 singleton object
companion object
2.控制结构和function函数
2.1 条件表达式
if(tiaojian) 1 else ()
a:可以将条件表达式赋值给一个val 常量值
b: 如果有多个语句 则使用{}
c:如果else没有值,则使用(),
d:每个语句后的;并不是强制的,但是如果两个不同的语句在同一行,则需要用;分割
e:如果在一行中有个长的语句(需要换行到第二行),则需要在此行末尾保证并不是结束符 ,例如:
Java代码
- s = s0 + (v - v0) * t + // The + tells the parser that this is not the end
- 5 * (a - a0) * t * t
2.2 块表达式和赋值
a:{} block 包含一串顺序表达式,
b:{}block结果也是一个是表达式,
c:block的值 等于最后一个语句的值
例如:
Java代码
- val distance = {
- val dx = x - x0;
- val dy = y - y0;
- sqrt(dx * dx + dy * dy)
- }
- distance 的值为:sqrt(dx * dx + dy * dy)
d:赋值语句的返回值为 No Value,用() 表示,表示Type Unit
例如:
Java代码
- { r = r * n; n -= 1 }
- 这个块的返回值为 {}
Java代码
需要注意:
Java代码
- x = y = 1 这个不允许,
- 因为y=1的返回值为{},不可能把一个常量值定义为{}
2.3 输入和输出
Java代码
- 输入:readLine 从console 读入一行
- readInt 从console 读入一个Int
- readDouble,
- readByte
- readShort
- readLong
- readFloat
- readBoolean
- readChar
Java代码
- 输出:print
- println
- printf:输出c风格的
- 例如:printf("Hello, %s! You are %d years old.\n", "Fred", 42)
2.4 循环
while:
Java代码
- while (n > 0) {
- r = r * n
- n -= 1
- }
for
a:for (i <- expr):
i遍历<-右边的表达式的值,至于i是何种类型,以来与表达式中每个元素的类型
例如:
Java代码
- val s = "Hello"
- var sum = 0
- for (i <- 0 until s.length) // Last value for i is s.length - 1
- sum += s(i)
b:for 循环中可以有多个 variable <- expression 形式,每个之间用;分割,
每个被称为generator
Java代码
- // Prints 11 12 13 21 22 23 31 32 33
- for (i <- 1 to 3; j <- 1 to 3) print((10 * i + j) + " ")
c:每个generator 可以定义个guard: guard 是个if的条件表达式
例如:
Java代码
- // Prints 12 13 21 23 31 32
- for (i <- 1 to 3; j <- 1 to 3 if i != j) print((10 * i + j) + " ")
d:可以 在 generator中 加入一些新的变量定义,用于循环
// Prints 13 22 23 31 32 33
for (i <- 1 to 3; from = 4 - i; j <- from to 3) print((10 * i + j) + " ")
e: 在循环体loop中使用yield 输出集合结果,输出的集合类型
由第一个generator的类型决定
Java代码
- for (i <- 1 to 10) yield i % 3
Java代码
- // Yields "HIeflmlmop"
- or (c <- "Hello"; i <- 0 to 1) yield (c + i).toChar
- // Yields Vector('H', 'e', 'l', 'l', 'o', 'I', 'f', 'm', 'm', 'p')
- for (i <- 0 to 1; c <- "Hello") yield (c + i).toChar
2.5 函数function
a:def functionName(param:Type):ReturnType={
}
b:如果非递归函数 对于ReturnType 可以省略,具体的返回类型则以
等号=右边最后一个表达式值的类型为准
c:如果是递归函数,则一定需要定义返回值类型
2.6 函数参数默认值
例如:
def decorate(str: String, left: String = "[", right: String = "]") =
left + str + right
可以使用如下方式调用
decorate("Hello")
decorate("Hello","<<<")
decorate(left = "<<<", str = "Hello", right = ">>>")
decorate("Hello", right = ">>>")
2.9 变长参数
函数的参数个数是变长的
例如:
Java代码
- def sum(args: Int*) = {
- var result = 0
- for (arg <- args) result += arg
- result
- }
- :val s = sum(1, 4, 9, 16, 25)
val s = sum(1 to 5) :这样的调用将会出错。
因为 参数类型是一个或多个int,而不是一个数字范围Range
如果需要传递一个数值范围,则需要告诉编译器将该范围作为一个 sequece 序列,
因此调用修改为
Java代码
上述代码修改为:
Java代码
- def sum(args: Int*) : Int = {
- if (args.length == 0) 0
- else args.head + recursiveSum(args.tail : _*)
- }
2.10 过程
一个没有返回值的函数,因此也就没有等于(=)这个
例如:
Java代码
- def box(s : String) { // Look carefully: no =
- val border = "-" * s.length + "--\n"
- println(border + "|" + s + "|\n" + border)
- }
或者
Java代码
- def box(s : String): Unit = {
- ...
- }
2.11 延迟赋值的常量值
将会在第一次使用的时候赋值,赋值的时候是以线程安全的形式进行,
因此第一次赋值的时候也是存在cost的
例如:
Java代码
- <pre class="java" name="code">// Evaluated as soon as words is defined
- val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString
- // Evaluated the first time words is used
- lazy val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString
- def words = scala.io.Source.fromFile("/usr/share/dict/words").mkString
- // Evaluated every time words is used</pre>
- <br>
2.12 exception
a:如何抛出异常
例如:
throw new IllegalArgumentException("x should not be negative")
抛出异常后,当前的操作将会终止。running time system 将会需要接收该异常的 handler 去处理异常,如果没有找到handler,程序将会终止。
b:scala 的方法并不需要定义异常。
在java 中 方法需要定义checked exception,
用于在编译时期检查这些异常是否已经定义和处理
c:throw 返回的类型为Nothing,这个在条件表达式中特别用效:
例如:
Java代码
- if (x >= 0) {
- sqrt(x)
- } else throw new IllegalArgumentException("x should not be negative")
- 第一个分支的饭胡
e:使用try{}catch{} 来捕获异常
Java代码
- try {
- process(new URL("http://horstmann.com/fred-tiny.gif"))
- } catch {
- case _: MalformedURLException => println("Bad URL: " + url)
- case ex: IOException => ex.printStackTrace()
- }
- 说明:如果定义一个不会被使用的变量,可以使用_
f:使用try{}finally{}来关闭资源
例如:
Java代码
- var in = new URL("http://horstmann.com/fred.gif").openStream()
- try {
- process(in)
- } finally {
- in.close()
- }
g:try{}catch{}finally{}模式来处理
等同与 try{try{}catch{}}finally{}