Scala学习笔记-基础语法
上手学习Scala语言。先熟悉一下语法。对于Scala笔者也是完全的新手,对scala的设计思想和实现原理没有太多了解。错误在所难免,还望发现后不吝指教。
Hello World
基础环境配置直接利用IntelliJ提供的Scala插件,会自动下载Scala开发包并配置好开发环境。直接从我们熟悉的“Hello world”开始对Scala的认知过程。
1
2
3
4
5
6
7
8
9
10
11
/**
* Scala 基础语法
*
* @author li.hzh
* @date 2016-09-14 23:37
*/
object SyntaxBasis {
def main(args: Array[String]): Unit = {
println("Hello world");
}
}
这里def main(args: Array[String]) 是一切scala程序的入口。
换行符
与Java相同,scala同样用分号;作为换行符,但不是必须的。一行只有一个语句的时候可以省略分号。不过笔者还是习惯都加上分号。如: def main(args: Array[String]): Unit = { println(“Hello world”); println(“不用写分号”) println(“必须写分号”); println(“因为有这句。”) }
详情参考:http://www.runoob.com/scala/scala-basic-syntax.html
数据类型
与Java有较大区别,没有Java中的基本数据类型,只有int等基本数据类型的包装类。一切皆对象。scala继承关系图
其中Unit等同于Java中的void,所以我们的main函数代码里有个Unit的返回值。Nothing是一切对象的子类。Any是一切对象的基类。Null代表空值或者空引用。AnyRef是一切引用对象的超类。通过代码来理解一下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.coderli.scala.lab
/**
* Scala 数据类型
*
* @author li.hzh
* @date 2016-09-20 11:21
*/
object DataType {
def main(args: Array[String]) {
val aInt: Int = 2147483647
val aLong: Long = 9223372036854775807L;
val aFloat: Float = 3.2F;
val aDouble: Double = 3.2;
val aString: String = "Single Line String";
val mString: String =
"""Multiple Lines String
Line One
Line Two
Line Three
""";
println("a Int : " + aInt);
println("a Long: " + aLong);
println("a Float: " + aFloat);
println("a Double: " + aDouble);
println("Single Line String: " + aString);
println("Multiple Lines String: " + mString);
// 因为一切皆对象,所以可以直接进行API调用
println(aDouble.-(2));
// 验证数据类型继承关系
println(aDouble.isInstanceOf[Double]);
println(aDouble.isInstanceOf[Any]);
println(aString.isInstanceOf[AnyRef]);
println(aString.isInstanceOf[String]);
}
}
与Java的几个区别
- 变量声明类型在后,变量名在前,中间用冒号: 分隔,挺别扭。
- 字符串类型多了一个三引号,可直接写换行的字符串。
- 数据类型都是对象,可以直接调用封装的方法,与其他类型同等对待,不用再区分所谓的基本数据类型。
- 最后通过几个isInstanceOf函数,验证一下上面的继承关系图。
上述代码输出结果如下:
a Int : 2147483647
a Long: 9223372036854775807
a Float: 3.2
a Double: 3.2
Single Line String: Single Line String
Multiple Lines String: Multiple Lines String
Line One
Line Two
Line Three1.2000000000000002
true
true
true
true
详情参考:http://www.runoob.com/scala/scala-data-types.html
变量和常量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 变量和常量
*
* @author li.hzh
* @date 2016-09-20 13:56
*/
object ValAndVar {
def main(args: Array[String]) {
// 常量用val声明, 值不可修改。相当于final,此处省略了类型声明, 利用了Scala的类型推断
val a = 1;
var b = "String";
b = "StringChange";
println(b)
}
}
如果省略类型声明,则必须在声明时给予初始化值,以进行类型推断。不能修改常量值,否则会编译错误。
详情参考:http://www.runoob.com/scala/scala-variables.html
访问修饰符
scala里private和protected的作用域都比Java更严格,private修饰的成员,仅可以在类内访问,外部类亦不可以访问。protected修饰的成员,仅子类可访问,同包不可。
这里重点关注scala提供的作用域保护的特性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.coderli.scala.lab
import com.coderli.scala.lab.access.Demo
/**
* 访问修饰符
*
* @author li.hzh
* @date 2016-09-20 14:29
*/
object AccessModifier {
def main(args: Array[String]) {
new Demo().printDemo();
}
}
package access {
private[lab] class Demo {
def printDemo(): Unit = {
println("Print Demo");
}
}
}
Demo类声明为,对除了lab包内的类以外的类均不可访问。因此可以在lab包里AccessModifier的main函数里访问。如果仅仅声明为private class Demo, 则会提示无法访问,编译错误。这个特性在项目中隔离内外部代码访问上很有用处。
访问作用域修饰可使用private和protected。(效果相同?) 详情参考:http://www.runoob.com/scala/scala-access-modifiers.html
运算符和条件控制语句与Java基本相同,略。 详情参考: http://www.runoob.com/scala/scala-operators.html http://www.runoob.com/scala/scala-if-else.html
循环
scala里for循环的写法和特性上有比较明显的变化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* @author li.hzh
* @date 2016-09-20 14:53
*/
object Loop {
def main(args: Array[String]) {
var i = 0;
for (i <- 1 to 10) {
println("Value of i: " + i);
}
var j = 0;
for (i <- 1 to 3; j <- 1 until 3) {
println("Value of i: " + i);
println("Value of j: " + j);
}
val evenResult = for (i <- 1 to 10 if i % 2 == 0
) yield i;
println(evenResult)
for (i <- evenResult) {
println(i)
}
}
}
第一个就是普通的for循环输出从1-10 的数字
Value of i: 1
Value of i: 2
Value of i: 3
Value of i: 4
Value of i: 5
Value of i: 6
Value of i: 7
Value of i: 8
Value of i: 9
Value of i: 10
第二个实际相当于Java中的二层循环。输出所有可能的组合结果,有个细微的区别,对于变量j,使用了until代替to,所以j的取值范围不包括3。
Value of i: 1
Value of j: 1
Value of i: 1
Value of j: 2
Value of i: 2
Value of j: 1
Value of i: 2
Value of j: 2
Value of i: 3
Value of j: 1
Value of i: 3
Value of j: 2
第三个循环是Java没有的特性,yield,对于满足if条件的变量保存起来,存入返回值的数组。因此输出为:
2
4
6
8
10
函数部分是scala的核心,包含的特性较多,scala号称多范式语言支持函数式编程,,笔者准备在下篇文章里单独介绍。