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則像是結合了抽象類、接口,就像是一種能夠多繼承(接口)的抽象類。