scala入門1
1. Scala解析器
省略windows環境下Scala解析器安裝和環境變數配置,通過scala命令進入scala shell命令列。
1) 輸入表示式,計算出結果值
2) 定義變數
Scala中有兩種變數,val和var,val類似與java中的final,一旦初始化,val變數就不能被賦值。相反var如圖java中的非final變數,可以在生命週期中多次被賦值。
第一種定義的方式使用的是scala的型別推導能力,它能讓scala自動理解你省略的型別。第二種定義方式是定義變數時並指定型別,變數名和型別之間用冒號隔開。第三種定義方式是簡化型別的方式。
注意:
對於val宣告的變數,重新賦值時,編譯器將會報錯。
而var宣告的變數,重新賦值時,則不會存在問題。
3) 函式定義
def函式定義開始,max函式名,x:Int、y:Int為函式引數名和型別,第三個Int表示函式返回值的型別,=號後面表示函式方法體。
對於函式返回值型別可以通過型別推導得到的可以不寫返回值型別,並且方法體只有一句程式碼的時候可以省略花括號,類似於:
一旦函式定義完成後,就可以通過函式名呼叫該方法。
定義一個既不帶引數又不帶返回結果的方法。
其中greet是方法名,空白的括號表示方法不帶引數,Unit是greet的結果型別,指的是函式沒有有效的返回值,scala的Unit型別類似於java的void型別,而實際上
4) 編寫scala指令碼
建立一個名為hello.scala的檔案,檔案內容為:
println("hello world, from a script!")
然後命令列執行,執行結果為:
5) while,foreach,for
(1)在指令碼中使用while迴圈,並用if判斷
建立while.scala檔案,檔案內容為:
var i = 0
while(i < args.length){
if(i != 0)
print(" ")
print(args(i))
i += 1
}
執行命令,輸出結果為:
(2)在指令碼中使用foreach
建立foreach.scala檔案,檔案內容為:
args.foreach(arg => println(arg))
執行命令,輸出結果為:
還有一種簡化方法,如果函式字面量只有一條語句,並且只有一個引數時,可以省略該引數,因此檔案內容也可以簡化為:
args.foreach(println)
建立for.scala檔案,檔案內容為:
for(arg <- args)
println(arg)
執行命令,輸出結果為:
6) 型別引數化陣列Array
建立array.scala檔案,檔案內容為:
val arrays = new Array[String](3)
arrays(0)="hello"
arrays(1)=","
arrays(2)="scala"
for(i <- 0 to 2)
print(arrays(i))
執行命令,輸出結果為:
7) 列表List
注意:scala.List不同於java.util.List,一旦建立就不可變。
建立list.scala檔案,檔案內容為:
val list1 = List(1,2,3)
val list2 = 0::list1
val list3 = list1:::list2
list3.foreach(println)
執行命令,輸出結果為:
8) 元組Tuple
與列表一樣,元組也是不可變的,但與列表不同的是,元組可以包含不同型別的物件。
建立tuple.scala檔案,檔案內容為:
val tuple = ("ABC",123)
println(tuple._1)
println(tuple._2)
執行命令,輸出結果為:
9) 集(Set)和對映(Map)
1) 可變集
建立mutable_set.scala,檔案內容為:
import scala.collection.mutable.Set //引入可變集
val mutSet = Set("hello","scala")
mutSet += "spark"
println(mutSet)
執行命令,輸出結果為:
2) 不可變集
建立immutable_set.scala檔案,檔案內容為:
import scala.collection.immutable.Set//引入不可變集
val immutSet1 = Set("hello","scala")
val immutSet2 = immutSet1.+("spark") //返回一個新的Set
println(immutSet2)
執行命令,輸出結果為:
注意:預設情況下引入的是不可變集
3) 可變對映
建立mutable_map.scala檔案,檔案內容為:
import scala.collection.mutable.Map //引入可變對映
val mutMap = Map[Int,String]()
mutMap += (1 -> "hello")
mutMap += (2 -> "scala")
mutMap += (3 -> "spark")
println(mutMap(2))
執行命令,輸出結果為:
4) 不可變對映
建立immutable_map.scala檔案,檔案內容為:
import scala.collection.immutable.Map //引入可變對映
val immutMap1 = Map[Int,String]()
val immutMap2 = immutMap1.+(1 -> "scala") //返回一個新的對映
println(immutMap2)
執行命令,輸出結果為:
2. Scala類和物件
1) 類、欄位和方法
類是物件的藍圖,一旦你定義了類,就可以用關鍵字new根據類的藍圖來建立物件。
欄位,不管用val還是var定義的,都是指向物件的變數。欄位的另一個說法是例項變數,因為每個例項都有自己的變數集。
傳遞給方法的任何引數都能夠在方法內部使用,Scala方法引數的一個重要特徵是他們都是val,不是var。
如果去掉方法體前面的等號,那麼方法的結果型別就必定是Unit。這種說法不論方法體裡面包含什麼都成立,因為scala編譯器可以把任何型別轉化為Unit。
2) 分號推斷
Scala程式裡,語句末尾的分號通常是可選的。願意也可以加,當然如果一行只有一條語句也可以省略,當一行超過一條語句是,則分號是必須的。
分號推斷的規則:
分割語句的具體規則既出人意料地簡單又非常有效。那就是,除非以下情況的一種成立,否則行尾被認為是一個分號:
疑問行有一個不能合法做為語句結尾的字結束,如句點和中綴操作符。
下一行開始於不能作為語句開始的詞。
行結束為括號(...)或方括號[...]內部,因為這些符號不能容納多個語句。
3) Singleton物件
Scala不能定義靜態成員,而是代之以定義單例物件(singleton object),除了用object關鍵字替換class關鍵字以外,單例物件的定義看上去和類的定義一致。
伴生物件:當單例物件與某個類共享一個名稱時,它就被稱作這個類的伴生物件。類和它的伴生物件必須定義在一個原始檔裡。類被稱為這個單例物件的伴生類。類和它的伴生物件可以互相訪問其私有成員。
建立ClassT.scala檔案,檔案內容為:
class ClassT { //伴生類
private val cnum = 1; //私有方法
private def add1() {
println(ClassT.onum.+(1)); //訪問伴生物件的私有屬性
}
}
object ClassT { //伴生物件
private val onum = 2; //私有屬性
def add2() {
val c = new ClassT //例項物件
println(c.cnum.+(1)) //伴生類私有屬性
c.add1()
}
}
object cT1 extends App{ //測試物件
ClassT.add2()
}
執行命令,輸出結果為:
2
3
類和單例物件的差別是:單例物件不帶引數,而類可以。特別需要指出的是,單例物件在第一次被訪問的時候才會被初始化。
3. 基本型別和操作
1) 基本型別
注意:除了String歸於java.lang包,其餘所有的基本型別都是scala的成員。
Scala的基本型別與java對應的基本型別的返回完全一樣。
2) 字面量
所有的基本型別都可以寫成字面量(literal),字面量就是直接寫在程式碼裡的常量值。
3) 操作符和方法
任何方法都可以是操作符。
建立MethodT.scala檔案,檔案內容為:
class MethodT {
private var num = 0
def add(a:Int){ //add方法 a為引數
num += a
println(num)
}
}
object mT1 extends App{
val mt = new MethodT
mt add 1 //將add方法作為中綴操作符使用
}
執行命令,輸出結果為:
1
中綴操作符:呼叫的方法位於物件和傳遞給方法的引數或若干引數之間。
字首操作符:方法名被放在呼叫的物件之前,如+、-、!、~。
字尾操作符:不用點或者括號呼叫的不帶任何引數的方法。
4) 物件相等性
Scala中如果想要比較一下看看兩個物件是否相等,可以使用==,或者它的反義!=。
Scala中==已經被仔細加工過,因此子啊多數情況下都可以實現合適的相等性比較。這種比較遵循一種非常簡單的規則,首先檢查左側是否為null,如果不是,則呼叫左運算元的equals方法。
Scala的==和Java的有何差別
Java裡==既可以比較原始型別也可以比較引用型別。對於原始型別,Java的==比較的是值相等,與Scala一致。而對於引用型別,Java的==比較了引用相等性,也就是說比較的是兩個變數是否都指向JVM堆裡的同一個物件。Scala也提供了這種機制,名字是eq。不過eq和它的反義詞ne,僅僅應用於直接對映到Java的物件。