一、变量定义
注意:在scala中没有static的概念,在object这个关键字修饰的类中所有的方法和属性都是static的。这里的object类叫做伴生类,目前不涉及。
oobject test01 {
def main(args: Array[String]): Unit = {
/**
* scala有两种变量val和var,val类似于java中的final变量,
* 一旦val初始化后就不能再赋值。与之对应var如同java中的
* 非final变量,var可以在它的生命周期中被多次赋值
*/
// 用字符串初始化了msg,scala推断msg的的类型是String,
val msg: String = "hello world" // 定义一个常量
println(msg)
// 对msg重新赋值就无法编译成功,提示 Reassignment to val
// msg = "hello world, again"
var greeting: String = "how are you" // 定义一个变量
// 对greeting进行重新赋值
greeting = "how are you, again"
println(greeting)
}
}
二、数据类型
Byte、Char、Short、Int、Long、Float、Double (无包装类型)和Boolean、Unit类型。scala中的数据类型都是对象,因此每种数据类型都可以调用该对象的很多方法
Unit表示无值,和Java中void等同。用作不返回任何结果的方法的结果类型,但是在scala中表现形式为()
Any:所有变量的父类,类似于java中的Object
AnyVal:Byte、Char、Short、Int、Long、Float、Double、Boolean、Unit
AnyRef:除了上面的九种是Anyval,其他都是AnyRef类型
特殊类型
Unit:unit等价于java中的void,只有一个实例值()
Null:Null类只有一个实例对象,null,类似于java中null引用,null可以赋值给任意的引用
类型(AnyRef),但是不能赋值给值类型(AnyVal)
Nothing:Nothing类型在scala的类层级的最低端,它是任何其他类型的子类型。
当一个函数,我们确定没有正常的返回值,可以用Nothing来指定返回类型。
这样有一个好处,就是我们可以把返回的值(异常)赋给其他的函数或者变量(兼容性)
我们可以通过下面一张图直观的理解scala的数据类型:
说明:
1) 在scala中有一个根类型Any,它是所有类的父类。
2) scala中一切皆为对象,分为两大类 AnyVal(值类型),AnyRef(引用类型),它们都是Any子类。
3) Null类型是scala的特别类型,它只有一个值null,它是bottom class,是所有AnyRef类型的子类。
4) Nothing也是bottom class,它是所有类的子类,在开发中通常可以将Nothing类型的值返回给任意变量或者函数。
下面进行一些基本类型的操作:
/**
* scala为它的基本类型提供了丰富的操作符集
*/
val sum = 1 + 2
/**
* abstract def
* +(x: Int): Int
* Returns the sum of this value and x.
* 我们从官方API中可以看到Int本身提供了一个+方法,接收一个Int参数并返回Int类型
* 除此之外还提供了其他类型 Float/Double/Long/Int/Char/Short/Byte/String 的入参方法
*/
val sumMore = (1).+(2) // 此处 1 + 2 与 (1).+(2) 是一样的,就是Int类包含了一个+方法,
/**
* 注意: scala中的操作符不是特殊的语法,任何方法都是操作符.使用方法的方式使他成为操作符,
* 如果写成 s.indexOf('o') ,indexOf就不是操作符,不过如果写成 s indexOf 'o' ,那么indexOf
* 就是操作符了,
*/
val s = "hello, world"
val res = s indexOf 'o' // scala调用了s.indexOf('o')
println(res)
println(s.toUpperCase)
println(s toUpperCase)
/**
* 数学运算
*/
println(1.2 + 2.5) // 3.5
println(3 - 1) // 2
println('b' - 'a') // 1
println(2L * 3L) // 6
println(11 / 4) // 2
println(11 % 4) // 3
println(11.0f / 4.0f) // 2.75
println(11.0 % 4.0) // 3.0
/**
* 关系符操作
*/
println(1 > 2) // false
println(1 < 2) // true
println(1.0 <= 1.0) // true
println(3.5f > 3.6f) // false
println('a' > 'A') // true
/**
* 对象相等性
*/
// 基本类型的判断
println(1 == 2) // false
println(1 != 2) // true
println(2 == 2) // true
// 也可以进行对象的对等性判断
println(List(1, 2, 3) == List(1, 2, 3))
println(List(1, 2, 3) == List(1, 3, 5))
三、懒值
// 在x被定义的时候即被取值
val x = "no lazy"
// 在y被首次使用时取值
lazy val y = "has lazy"
四、表达式
/**
* 在表达式${}中必须加s前缀,
* 可以进行一些数值的计算,直接引用前面定义的变量名
*/
val name = "rock"
println(s"${name}") // 输出rock
println(s"${4 * 4}") // 输出16
五、条件判断
// 在scala中像java一样,没有三元运算符
/**
* if() {} else {},其中{}中最后一行代码是返回值
* if() {} else if () {} 可以不写最后的else,
* 如果执行到最后的else,编译器会帮我们返回一个Unit类型,这在java中会报错!
*/
var i = 9 // 此处i会被推导了Int类型
val t = if (i > 10) i else "rock" //在这里编译器会将t推导为Any类型
println(t)
六、循环
1). while循环
var j = 0
// while循环中通过索引来获取args中元素
while (j < args.length) {
println(args(j))
j + 1
}
2). foreach循环
// arg为args中的每一个元素
args.foreach((arg) => println(arg))
// args中只有一个元素时可以用下面这个方式
args.foreach(println)
3). for循环
// arg 为val类型
for (arg <- args) {
println(arg)
}
// for循环中过滤 ,我我们可以通过添加if条件来过滤不需要的数据,多个条件可以用';'进行分割
for (arg <- args if arg.startsWith("H");if arg.contains("w")) {
println(arg)
}
七、异常
// 抛出异常
val n = 3
if (n % 2 == 0) {
n / 2
} else {
throw new RuntimeException("n must be even")
}
try {
2 / 0
} catch {
// 捕获异常
case ex: IllegalArgumentException => {
println("handle IllegalArgument")
}
case ex: IndexOutOfBoundsException => {
println("handle IndexOutOfBounds")
}
} finally {
// 无论方法如何中止,该部分代码都会执行
println("always execute")
}
}
八、match
/**
* scala中的匹配表达式可以有多个选项,类似于java中的switch
*/
val firstArg = if (args.length > 0) args(0) else ""
firstArg match {
case "apple" => {
// handle code
println("apple")
}
case "banana" => {
println("banana")
}
case _ => {
println("no match")
}
}