Scala 基础语法

本文详细介绍了Scala的基础语法,包括常量和变量、基本类型、操作符、内建控制结构、函数特性如高阶函数、闭包、可变参数、尾递归等,并深入探讨了Scala的OOP特性,如单例对象、类、重写和重载、无参方法。此外,文章还涵盖了集合、泛型、延迟初始化(lazy)以及Option的使用,展示了Scala的灵活性和强大的函数式编程能力。
摘要由CSDN通过智能技术生成

Scala 基础语法

Scala是多范式的编程语言,本教程着重介绍函数式编程.

本教程适用于已经掌握了Java编程语言的人.

常量和变量

var可以用来声明一个变量:

var var_name[:type] = xxx

其中,属性的类型声明可以省略.那么scala会自动推测属性的类型.即使类型可以省略,scala和python不一样,还是有类型的区别的.

Scala官方不建议定义过多变量,最好不要定义任何变量(所有变量的效果通过函数完成).

val可以用来声明一个常量:

val val_name[:type] = xxx

常量不可以被修改.

基本类型

Scala提供以下的基本数据类型:

类型 说明
Byte 字节类型
Short 短整型
Int 整型
Long 长整型
Char 字符
String 字符串
Float 浮点型
Double 双精度
Boolean 布尔

除了String,位于java.lang中,其余的基本类型都处于scala的包下.Scala没有所有真正基本类型的概念,实际上全部都是封装类.但是这些基本类型可以直接在scala中赋值(不需要通过new来赋值).

scala和java.lang包会自动被scala引入,所以使用这些类不需要任何声明.

例如:

val flag = true
// 等价于
val flag: Boolean = true

在Scala中,String支持三引号的写法.”“”xxx”“”这样可以支持原生的字符串,在三引号中的字符串会被直接当作原生字符串处理,不需要任何转义.

Scala为基本类型提供了富包装类RichXxx.并且可以实现自动转换.

操作符

Scala中,操作符即方法,方法即操作符.scala中没有真正意义上的操作符,操作符实际上可以通过函数的方式调用:

// 以下两种写法是一样的:
val num1 = 2 + 3
val num2 = 2.+(3)

字面量2作为对象存在,对象中有+方法.

对于一个方法,可以用操作符的方法去调用:

// 以下两种写法一样:
val str1 = "123456".charAt(1)
val str2 = "123456" charAt 1

Scala没有真正意义上的操作符,所有的操作符都会被转换为方法的调用.

如果方法接收1个以上的参数,括号不能被省略,如果没有参数,可以省略点和括号:

val str1 = "123456".substring(2, 3)
val str2 = "123456" substring (2, 3)
val str3 = "a".toUpperCase()
val str4 = "a" toUpperCase

Scala中方法是有优先级的.在表达式中体现为操作符的优先级.对于一连串的方法调用,优先级高的方法会先得到调用.

优先级是按照方法的名字确定的,是按照方法的名称的第一个字符确定的,以下字符越靠前则优先级越高:

  1. * / %
  2. + -
  3. :
  4. = !
  5. <>
  6. &
  7. ^
  8. |
  9. 所有字母
  10. 所有赋值操作符

可以通过括号改变优先级,对于优先级相同的方法,是按照从左到右来调用的.

操作符分为三类:

  • 中缀操作符,操作符在两个操作数之间
  • 后缀操作符,操作符位于一个唯一的操作数的后面
  • 前缀操作符,操作符位于一个唯一的操作数的前面,Scala只提供四种: -, +, ~, %.前缀操作符会被翻译为”unary_x”,例如”-3”会被翻译为”3.unary_-()”,前缀操作符我们无法自己定义.

特殊的,以”:”字符为结尾的方法,是右操作数调用,传入左操作数.例如”a::b”会被翻译为”(b).::(a)”

内建控制结构

if可以用作判断,用法和java基本一样.但是scala中if有返回值,if在执行完毕后会将最后一个表达式的值给返回,例如:

val num = 10

val res = if (num > 100) {
    "num大于100"
}
else if (num < 100 && num > 5) {
    "num在5到100之间"
}
else {
    "num小于5"
}

println(res)

res的结果应该是”num在5到100之间”.if实际上是一种函数,不在函数中进行打印满足函数式编程的理念.

while和do…while可以用于循环,和java用法基本一样.scala中的while的返回值是Unit,表示没有返回值.while需要用到变量,并且可能产生额外的影响,不符合函数式编程的思想,所以官方不建议使用while编写循环,建议使用递归替换.

例如,使用递归实现1到100的计算:

def sum100(x: Int, sum: Int): Int = {
    if (x <= 100) {
        sum100(x + 1, sum + x)
    }
    else {
        sum
    }
}

val res = sum100(1, 0)
println(res)

所有的循环控制都应该被写成这样的递归形式.

for的使用和java也是类似的.可以使用for来遍历集合:

val list = List(1, 3, 4, 5, 12)
for (x:Int <- list) {
    println(x)
}

to运算符用于生成一个范围的数组,可以直接用于一定范围的循环:

for (x <- 1 to 5) {
    println(x)
}

for还可以实现过滤,例如可以通过下面代码遍历0-100的偶数:

for (x <- 0 to 100; if x % 2 == 0) {
    println(x)
}

使用多个”;”可以实现多个条件的过滤:

for (x <- 0 to 100; if x > 20; if x < 80) {
    println(x)
}

使用for可以实现嵌套循环.

for (i <- 1 to 9; j <- 1 to i) {
    print(i * j + ",")
}

这打印了10以内的所有乘法的结果.

for还支持流间变量定义,可以在多循环中定义一个共享的变量.流间变量支持使用if进行赋值,例如通过下面的代码打印完整的九九乘法表:

for (i <- 1 to 9; j <- 1 to i; next = if (i == j) "\n" else "\t") {
    print(i + "*" + j + "=" + i * j + next)
}

for的返回值也是Unit.但是yield可以让for把每次循环最后一次返回值组装为一个集合返回.所以上面的代码可以转换为:

val res = for (i <- 1 to 9; j <- 1 to i; next = if (i == j) "\n" else "\t") yield {
    i + "*" + j + "=" + i * j + next
}

println(res)

这就满足了函数式编程的要求.

scala继承了java的异常机制,通过throw关键字可以抛出异常,通过try…catch…finally可以捕获异常.

catch的写法和java不同,为:

try {
    ...
} catch {
    case e: Exception1 => ...
    case e: Exception2 => ...
    ...
} finally {
    ...
}

try可以带有返回值.例如:

val res = try {
    ...
    "no exception"
} catch {
    case e: Exception => "have an exception"
}

println(res)

注意如果在finally中返回,这个返回值不会对try和catch的返回值产生影响,这点和java不一样(java的话无论如何都会返回finally的返回值).

match … case类似于java的switch … case.下面是示例:

val str = "abc"
val res = str match {
    case "abc" => "我是abc"
    case "bbb" => "我是bbb"
    case _ => "我既不是abc也不是bbb"
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值