简介
Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成面向对象编程和函数式编程的各种特性。
Scala 运行在 Java 虚拟机上,并兼容现有的 Java 程序。
Scala 源代码被编译成 Java 字节码,所以它可以运行于 JVM 之上,并可以调用现有的 Java 类库。基础语法
交互式编程
$ scala
scala> 1 + 1
res0: Int = 2
脚本式编程
object HelloWorld{
def main(args: Array[String]): Unit = {
println("Hello word")
}
}
// scalac HelloWorld.scala
// scala HelloWorld
基本语法规范
- Scala 大小写敏感
- 类名首字母大写(大驼峰)
- 方法名首字母小写(小驼峰)
- 程序名与文件名相同
- main() 是脚本入口
scala 编成规范 基本尊崇 java 编成规范
数据类型
![](https://img.haomeiwen.com/i28164900/051d1c71dbac51cb.png)
变量与常量
- 变量: 在程序运行过程中其值可能发生改变的量叫做变量。如:时间,年龄。
- 常量: 在程序运行过程中其值不会发生变化的量叫做常量。如:数值 3,字符'A'。
在 Scala 中,使用关键词 "var" 声明变量,使用关键词 "val" 声明常量
基本语法格式
var VariableName : DataType [= Initial Value]
val VariableName : DataType [= Initial Value]
// 如果DataType可以被类型推断 则DataType可以省略
var myVar : String = "游瑞"
val myVal = "Hello, Scala!";
val xmax, ymax = 100 // xmax, ymax都声明为100
修饰符
Scala 访问修饰符基本和Java的一样,分别有:private,protected,public。
如果没有指定访问修饰符,默认情况下,Scala 对象的访问级别都是 public。
Scala 中的 private 限定符,比 Java 更严格,在嵌套类情况下,外层类甚至不能访问被嵌套类的私有成员。
分支语句
if - else
if(布尔表达式)
{
// 如果布尔表达式为 true 则执行该语句块
}
// 没有 elif 语法
match (模式匹配)
// 值匹配
def matchTest(x: Int): String = x match {
case 1 => "one"
case 2 => "two"
case _ => "many"
}
// 类型匹配
selectedValue match {
case x: Int => println("Int " + x)
case y: Double => println("Double " + y)
case z: String => println("String " + z)
case _ => throw new Exception("not match exception")
}
// 其他
case 0 | "" => false //在0或空字符串的情况下,返回false
case 2 | 4 | 6 | 8 | 10 => println("偶数") //在10及以下的偶数,返回"偶数"
case x if x == 2 || x == 3 => println("two's company, three's a crowd") //在模式匹配中使用if
循环语句
while
while(condition)
{
statement(s);
}
do - while
do {
statement(s);
} while( condition );
for
数字循环
for( var x <- Range){
statement(s);
}
for( a <- 1 to 3; b <- 1 to 3){
println( "Value of a: " + a );
println( "Value of b: " + b );
}
列表循环
for( x <- List ){
statement(s);
}
val numList = List(1,2,3,4,5,6);
for( a <- numList ){
println( "Value of a: " + a );
}
循环守卫
for( var x <- List
if condition1; if condition2...
){
statement(s);
}
// 分号(;)来为表达式添加一个或多个的过滤条件
yield
var retVal = for{ var x <- List
if condition1; if condition2...
}yield x
// retVal 会形成一个列表
函数
函数定义
def functionName ([参数列表]) : [return type] = {
function body
return [expr]
}
函数调用
functionName( 参数列表 )
[instance.]functionName( 参数列表 )
demo
object Test {
def main(args: Array[String]) {
println( "Returned Value : " + addInt(5,7) );
}
def addInt( a:Int, b:Int ) : Int = {
var sum:Int = 0
sum = a + b
return sum
}
}
闭包
var factor = 3
val multiplier = (i:Int) => i * factor
这里我们引入一个自由变量 factor,这个变量定义在函数外面。
这样定义的函数变量 multiplier 成为一个"闭包",因为它引用到函数外面定义的变量,定义这个函数的过程是将这个自由变量捕获而构成一个封闭的函数。
类和对象 (class|object)
类是对象的抽象,而对象是类的具体实例。类是抽象的,不占用内存,而对象是具体的,占用存储空间。类是用于创建对象的蓝图,它是一个定义包括在特定类型的对象中的方法和变量的软件模板。
Scala中的类不声明为public,一个Scala源文件中可以有多个类。
类与继承
由于 scala 的类与继承与 java 相同 这里不做详细赘述,只写一个demo,后面详细讲不一样的地方
import java.io._
class Point(val xc: Int, val yc: Int) {
var x: Int = xc
var y: Int = yc
def move(dx: Int, dy: Int) {
x = x + dx
y = y + dy
println ("x 的坐标点 : " + x);
println ("y 的坐标点 : " + y);
}
}
class Location(override val xc: Int, override val yc: Int,
val zc :Int) extends Point(xc, yc){
var z: Int = zc
def move(dx: Int, dy: Int, dz: Int) {
x = x + dx
y = y + dy
z = z + dz
println ("x 的坐标点 : " + x);
println ("y 的坐标点 : " + y);
println ("z 的坐标点 : " + z);
}
}
object Test {
def main(args: Array[String]) {
val loc = new Location(10, 20, 15);
// 移到一个新的位置
loc.move(10, 10, 5);
}
}
单例模式
在 Scala 中,是没有 static 这个东西的,但是它也为我们提供了单例模式的实现方法,那就是使用关键字 object。
Scala 中使用单例模式时,除了定义的类之外,还要定义一个同名的 object 对象,它和类的区别是,object对象不能带参数。
当单例对象与某个类共享同一个名称时,他被称作是这个类的伴生对象:companion object。你必须在同一个源文件里定义类和它的伴生对象。类被称为是这个单例对象的伴生类:companion class。类和它的伴生对象可以互相访问其私有成员。
// 私有构造方法
class Marker private(val color:String) {
println("创建" + this)
override def toString(): String = "颜色标记:"+ color
}
// 伴生对象,与类名字相同,可以访问类的私有属性和方法
object Marker{
private val markers: Map[String, Marker] = Map(
"red" -> new Marker("red"),
"blue" -> new Marker("blue"),
"green" -> new Marker("green")
)
def apply(color:String) = {
if(markers.contains(color)) markers(color) else null
}
def getMarker(color:String) = {
if(markers.contains(color)) markers(color) else null
}
def main(args: Array[String]) {
println(Marker("red"))
// 单例函数调用,省略了.(点)符号
println(Marker getMarker "blue")
}
}
特征(Trait)
Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。
与接口不同的是,它还可以定义属性和方法的实现。
一般情况下Scala的类只能够继承单一父类,但是如果是 Trait(特征) 的话就可以继承多个,从结果来看就是实现了多重继承。
Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait,如下所示:
trait Equal {
def isEqual(x: Any): Boolean
def isNotEqual(x: Any): Boolean = !isEqual(x)
}
特征构造顺序
特征也可以有构造器,由字段的初始化和其他特征体中的语句构成。这些语句在任何混入该特征的对象在构造时都会被执行。
构造器的执行顺序:
- 调用超类的构造器;
- 特征构造器在超类构造器之后、类构造器之前执行;
- 特征由左到右被构造;
- 每个特征当中,父特征先被构造;
- 如果多个特征共有一个父特征,父特征不会被重复构造
- 所有特征被构造完毕,子类被构造。
构造器的顺序是类的线性化的反向。线性化是描述某个类型的所有超类型的一种技术规格
正则表达式
Scala 通过 scala.util.matching 包中的 Regex 类来支持正则表达式。
val pattern = new Regex("(S|s)cala") // 首字母可以是大写 S 或小写 s
val str = "Scala is scalable and cool"
println((pattern findAllIn str).mkString(",")) // 使用逗号 , 连接返回结果
异常处理
抛出异常
throw new IllegalArgumentException
捕获异常
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
object Test {
def main(args: Array[String]) {
try {
val f = new FileReader("input.txt")
} catch {
case ex: FileNotFoundException => {
println("Missing file exception")
}
case ex: IOException => {
println("IO Exception")
}
} finally {
println("Exiting finally...")
}
}
}
网友评论