二、基础语法(2)
2.1标识符
//Scala中的标识符声明,基本和Java是一致的,但是细节上会有所变化。
- 首字符为字母,后续字符任意字母和数字,美元符号,可后接下划线_
- 首字符为操作符,后续字符为任意操作符(变量如果用运算符,那么后面全都应该用运算符)
- Scala中有些保留字,不能用作标识符,但是反引号括起除外,如yield在Scala中就是保留字
- 用反引号`....`包括的任意字符串,即使是关键字也可以
2.2变量
//Scala声明变量有两种方式,一个用val,一个用var。
//val / var 变量名 : 变量类型 = 变量值。
//val定义的值是不可变的,它不是一个常量(像1,2,3才是常量),是不可变量,或称之为只读变量。
2.3常用类型
//Scala常用类型中包含有8种数值类型:Byte、Char、Short、Int、Long、Float、Double及Boolean类型,另外还有String类型(scala中的String使用的是Java中的String)。
注意:既然Java的基本类型数据在Scala中都是对象,那么也就意味着Java中基本类型的数据在Scala中都是可以调用对象方法的。
特别关注Unit(表示过程,无明确返回,类比void),Nothing(所有类型的子类型,可以作为没有正常返回值的方法的返回类型),Null(所有引用类型的子类型)
2.4算术操作符重载
//+-*/%可以完成和Java中相同的工作,但是有一点区别,Scala是完全面向对象语言,所以所有的运算符都是对象的运算行为,也就是所谓的对象方法。
注意:Scala中没有++、--操作符,需要通过+=、-=来实现同样的效果。
2.5调用函数和方法
- 调用函数,求方根(需要先导入这个包,这里_指的是*。可以直接引用。Scala的包不仅仅用于管理类,还可以当成对象使用,所以倒包时等同于将包的对象引用到当前环境中,所以包对象中的所有方法都可以直接使用)
- 调用方法,静态方法(scala中没有静态方法这个概念,需要通过类的伴生对象来实现)
- 用方法,非静态方法,使用对象调用
三、控制结构
3.1if-else
var result = if ( sumVal == 0 ) { println("true") // 此处为满足条件逻辑的最后一行内容,打印语句是没有返回值的 } else { "false" //此处为不满足条件逻辑的最后一行内容,此处返回值为字符串String }
|
注意:如果大括号内的逻辑代码只有一行,大括号可以省略
Scala中任意表达式都是有返回值的,也就意味着if else表达式其实是有返回结果的,具体返回结果的值取决于满足条件的代码体的最后一行内容
3.2while(使用较少)
var n = 1; val while1 = while(n <= 10){ n += 1 } println(while1) println(n) While语句本身没有值,即整个While语句的结果是Unit类型的() |
注:因为while和do…while中没有返回值,所以当要用该语句来计算并返回结果时,就不可避免的使用变量 ,而变量需要声明在while循环的外部,那么就等同于循环的内部对外部的变量造成了影响, 也就违背了函数式编程的重要思想,所以不推荐使用。
3.3for
//Scala 也为for 循环这一常见的控制结构提供了非常多的特性,这些for 循环的特性被称为for 推导式(for comprehension)或for 表达式(for expression)。
//变量在左边,范围或集合在右边。
- 范围数据循环1:to左右两边为前闭后闭的访问
for(i <- 1 to 3){ print(i + " ") } |
- 范围数据循环2:until左右两边为前闭后开的访问
for(i <- 1 until 3) { print(i + " ") } |
- 逆序循环
for(i <- (1 until 3).reverse) { print(i + " ") } |
- 自定义步长
for(i <- 1 until (9,2)) { print(i + " ") } |
- 循环守卫:引入循环保护式(也称条件判断式,守卫)。保护式为true则进入循环体内部,为false则跳过,类似于continue
for(i <- 1 to 10 if i %3= 0) { print(i + " ") } |
- 引入变量(没有关键字,所以一定要加;来隔断逻辑)
for(i <- 1 to 3; j = 4 - i) { print(j + " ") } |
- 嵌套循环(没有关键字,所以一定要加;来隔断逻辑)
for(i <- 1 to 3; j <- 1 to 3) { print(i*j + " ") } |
- 循环返回值:(将遍历过程中处理的结果返回到一个新集合中,使用yield关键字)
val for5 = for(i <- 1 to 10) yield i |
- 使用花括号{}代替小括号()
for{ i <- 1 to 3 j = 4 - i} |
注意:{}和()对于for表达式来说都可以。for 推导式有一个不成文的约定:当for 推导式仅包含单一表达式时使用原括号,当其包含多个表达式时使用大括号。值得注意的是,使用原括号时,早前版本的Scala 要求表达式之间必须使用分号。
3.4循环中断
//在java 中,循环中断一般使用break 和continue来处理,二者不同在于退出的范围。
//在scala中,我们通过break来中断循环,中断的范围通过breakable关键词来锁定范围。
// breakable {//break for (i <- 1 to 9; j <- 1 to i) { breakable {//continue if (i == 5) break() print(j + "*" + i + "=" + i * j) if (i == j) println() else print("|") } } // } |
四、函数
4.1可变参数(不确定个数参数,类似Java的...)(求和,不知道传几个。()中:前面是集合,后面是变量类型后带上*)
def f7(args: Int*) = { var result = 0 for(arg <- args) (遍历) result += arg result } |
4.2递归函数
//必须有明确的返回值类型 def f8(n: Int): Int = { if(n <= 0) 1 else n * f8(n - 1) } |
4.3惰性函数
//当函数返回值被声明为lazy时,函数的执行将被推迟,直到我们首次对此取值,(要用到值时才加载这个函数,所以此次加载是1,2)。这种函数我们称之为惰性函数,在Java的某些框架代码中称之为懒加载(延迟加载,可理解为何时使用何时加载)
def f10(): String = { println("f10方法执行") //2 } lazy val msg = f10() println("f10方法没有执行") //1 println(msg) |
注意:定义lazy的变量必须是val,不允许var
五、异常
//Scala提供try和catch块来处理异常。try块用于包含可疑代码。catch块用于处理try块中发生的异常。可以根据需要在程序中有任意数量的try...catch块。
// Scala try { val r = 10 / 0 } catch { case ex: ArithmeticException=> println("捕获了除数为零的算数异常") case ex: Exception => println("捕获了异常") } finally { // 最终要执行的代码 } |
- 我们将可疑代码封装在try块中。 在try块之后使用了一个catch处理程序来捕获异常。如果发生任何异常,catch处理程序将处理它,程序将不会异常终止。
- Scala的不会强行要求程序处理异常。
- 用throw关键字,抛出一个异常对象。所有异常都是Throwable的子类型。throw表达式是有类型的,就是Nothing,因为Nothing是所有类型的子类型,所以throw表达式可以用在需要类型的地方。
- 在Scala里,借用了模式匹配的思想来做异常的匹配,因此,在catch的代码里,是一系列case子句。
- 异常捕捉的机制与其他语言中一样,如果有异常发生,catch子句是按次序捕捉的。因此,在catch字句中,越具体的异常越要靠前,越普遍的异常越靠后。 如果抛出的异常不在catch字句中,该异常则无法处理,会被升级到调用者处。
- finally字句用于执行不管是正常处理还是有异常发生时都需要执行的步骤,一般用于对象的清理工作。
Scala提供了throws关键字来声明异常。可以使用方法定义声明异常。 它向调用者函数提供了此方法可能引发此异常的信息。 它有助于调用函数处理并将该代码包含在try-catch块中,以避免程序异常终止。在scala中,可以使用throws注释来声明异常 @throws(classOf[NumberFormatException]) //等同于NumberFormatException.class def f11() = { "abc".toInt } |