Scala的程序被编译成Java字节码(生成class文件),因此能够运行在JVM上,而且能够调用Java的类库,兼容Java程序。java
Scala 是一门多范式(multi-paradigm)的编程语言,设计初衷是要集成OOP和函数式编程(FP)的各类特性:正则表达式
Scala比较流行的Web框架:Lift框架、Play框架。编程
一、脚本编程:运行一个HelloWorld的程序(保存到HelloWorld.scala文件中,文件名应与类名相同,不然没法编译):数组
object HelloWorld { def main(args: Array[String]): Unit = { println("Hello, world!") } }
在终端中,运行:scala HelloWorld.scala,便可输出。安全
二、Scala也能够交互式编程(进入终端):闭包
当要使用的标识符(方法名等)与关键字冲突之时,要使用这个标识符就须要写在一对倒引号`之间,如线程的yield方法:Thread.`yield`()。并发
定义Scala的包:框架
一、第一种方法相似于Java,在一个文件开头定义包名,则该文件后面的全部代码都属于这个包:编程语言
package com.qunyh; class HelloWorld() { }
二、第二种方法相似于C#,指明包的做用域,因而一个文件中能够定义多个包:ide
package com.qunyh { class HelloQunyh { } }
引用包(能够引用Java的包):
import java.awt.Color //只引入Color类 import java.awt._ //引入包内全部成员
多行字符串:
val foo = """菜鸟教程
www.runoob.com
www.w3cschool.cc
www.runnoob.com
以上三个地址都能访问"""; //这是一个字符串,只不过是分多行:在一对"""之间
变量的声明:
通常变量用var声明,常量用val声明(这种声明的常量值之后就不能修改了,否则编译会报错)。
//能够指明变量类型(这种声明的时候能够不用初始化): 注意类型的位置 var myVar : String = "Foo"; val myVal : String = "Foo"; //也能够不指明(此时必须初始化,才能类型推断) var yourVar = "Foo"; val yourVal = "Foo"; //多个变量一块儿声明 var xmax, ymax = 100; //两个变量值都为100
声明一个元组:
访问修饰符:
基本和Java同样,若是没有指定,默认访问级别是public。可是Scala的限定比Java更严格。
for循环:
一、第一种结构是for( var x <- Range ):其中Range区间能够是i to j或者i until j;而左箭头<-用于为变量x赋值。
object HelloWorld { def main(args: Array[String]): Unit = { var x = 0; //for(x <- 1 to 10) for(x <- 1 until 10) { println("hello"); } } }
object Test { def main(args: Array[String]) { var a = 0; var b = 0; // 至关于二重循环: //for(int a = 1; a <= 3; a++) // for(int b = 1; b <= 3; b++) for( a <- 1 to 3; b <- 1 to 3){ println( "Value of a: " + a ); println( "Value of b: " + b ); } } }
二、第二种结构for( var x <- List ):其中 List 变量是一个集合,for 循环会迭代全部集合的元素:
object Test { def main(args: Array[String]) { var a = 0; var numList = List(1, 2, 3, 4); for(a <- numList) { println(a + ""); } } }
与其余的动态语言相似,Scala也有过滤器:
object Test { def main(args: Array[String]) { var a = 0; var numList = List(1,2,3,4,5,6,7,8,9,10); for(a <- numList if a % 2 == 0; if a < 5) { println(a + ""); } } }
并且还能够把List中过滤后剩下的,做为新的List返回(只是这种for循环的写法有点不一样):
object Test { def main(args: Array[String]) { var a = 0; var numList = List(1,2,3,4,5,6,7,8,9,10); var retList = for{ a <- numList if a % 2 == 0; if a < 5 } yield a; //这种for循环就不带循环体了 for(a <- retList) { println(a + ""); } } }
Scala的循环控制语句没有break、continue等,可是提供了另外一种语法来实现break语句的效果(须要导入control包)。
import scala.util.control._ object Test { def main(args: Array[String]) { var a = 0; var control = new Breaks; var numList = List(1,2,3,4,5,6,7,8,9,10); //建议 control.breakable { for(a <- numList) { println(a + ""); if(a == 5) { control.break; } } } for(a <- numList) { println(a + ""); if(a == 5) { control.break; } } } }
函数:
Scala 有函数和方法,两者在语义上的区别很小。Scala 方法是类的一部分,而函数是一个对象能够赋值给一个变量。咱们能够在任何地方定义函数,甚至能够在函数内定义函数(内嵌函数),可是做用域就受到了限制。
Scala 函数声明格式以下:
def functionName ([参数列表]) : [return type];
若是不写等于号和方法主体(只有声明),那么方法会被隐式声明为"抽象(abstract)",包含它的类型(在类中)因而也是一个抽象类型。
函数定义格式以下(含body),其中返回值能够是任意的Scala数据类型:
def functionName ([参数列表]) : [return type] = { function body return [expr] }
闭包:
Scala的闭包与C#的Lambda表达式相似,例如:
val multiplier = (i:Int) => i * factor; //这就是一个闭包:箭头的左边是形参,右边是body(可能含返回值)。整个闭包能够看成一个函数,赋给一个变量
Scala的字符串:
String类型:
Scala自己没有String类,其类型其实是Java String(java.lang.String),而Java的String对象的值是不可变的,若是修改字符串则意味着会产生一个新的字符串对象(暂时还没搞清楚,但我以为是这个意思:修改以前=右边是一个字符串常量对象,变量只是引用其地址,而修改以后就是建立了一个新的字符串常量对象,变量只是更改其引用地址)。与Java、C#相似,要建立一个可修改的字符串,可使用StringBuilder类。
StringBuilder类:
object Test { def main(args: Array[String]) { val buf = new StringBuilder; buf += 'a'; buf ++= "bcdef"; //都不会从新建立对象 println( "buf is : " + buf.toString ); } }
数组:
var z = Array("Runoob", "Baidu", "Google"); var z:Array[String] = new Array[String](3); //多维数组 var myMatrix = ofDim[Int](3,3); //合并数组 var myList1 = Array(1, 2, 3); var myList2 = Array(4, 5, 6); var myList3 = concat( myList1, myList2); //123456;concat函数:import Array._; //建立区间数组:使用range方法,返回一个数组Array var yourList1 = range(10, 20, 2); //arg3是步长,默认为1(不包含20)
集合:
Scala提供了一些集合类型的抽象,分为可变集合、不可变集合。
// 常见的集合: // 定义整型 List val x = List(1,2,3,4) // 定义 Set var x = Set(1,3,5,7) // 定义 Map val x = Map("one" -> 1, "two" -> 2, "three" -> 3) // 建立一个元组(这里包含两个不一样类型元素) val x = (10, "Runoob") // 定义 Option val x: Option[Int] = Some(5)
迭代器Iterator:
Iterator不是集合,而是一种访问集合的方法。迭代器的两个基本操做是next(返回集合中、迭代器的下一个元素,并更新迭代器自身的状态)和hasNext(判断集合中、迭代器的下一个元素是否存在)方法。能够先看代码,而后更容易理解:
object Test { def main(args: Array[String]) { val it = Iterator("Baidu", "Google", "Runoob", "Taobao"); while (it.hasNext){ println(it.next()) } //还能够利用迭代器,很方便的查找max、min var ita = Iterator(20,40,2,50,69, 90); println("最小:" + ita.min); //println("最小:" + ita.min); //println("最大:" + ita.max); //一个迭代器,max、min只能用一次(再用就不支持操做),就算是用两次min也不行 //个人理解是:迭代器是迭代地找max、min,找到即遍历完整个"集合",就中止迭代了, //再次使用就会抛出异常java.lang.UnsupportedOperationException //获取迭代器的长度size或length:便可以迭代的次数 //和min、max的用法类似:因此第一次是6,之后就是0了 var itb = Iterator(20,40,2,50,69, 90); println(itb.size + ":" + itb.length); //println(itb.size + ":" + itb.size); } }
Scala类与对象:
建立一个类和类的实例:
//Point类文件 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); } } //主函数 object Test { def main(args: Array[String]) { //建立一个Point对象 var pt = new Point(10, 20); pt.move(10, 10); } }
Scala继承:
//继承刚才的Point类:Location类文件 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]) { //建立一个Point对象 var lc = new Location(10, 20, 10); lc.move(10, 10, 10); } }
Scala Trait(特征):
特征至关于Java的接口,可是Scala的特征功能却更为强大。与接口不一样,特征能够定义属性,还能够定义方法的实现,而Java接口却不能有实现(只能是抽象方法,并且接口不能包含成员变量,除了 static 和 final 变量)。所以在这个方面Trait更像Java的抽象类(能够有抽象方法与非抽象方法),可是抽象类只能是单继承,因此我以为在Java中,接口就像是抽象类的精简版(只有定义,没有实现),而Scala Trait则像是结合了抽象类、接口,就像是一种能够多继承(接口)的抽象类。