1. 程式人生 > >scala入門1

scala入門1

1. Scala解析器

省略windows環境下Scala解析器安裝和環境變數配置,通過scala命令進入scala shell命令列。

1) 輸入表示式,計算出結果值


2) 定義變數

Scala中有兩種變數,valvarval類似與java中的final,一旦初始化,val變數就不能被賦值。相反var如圖java中的非final變數,可以在生命週期中多次被賦值。


第一種定義的方式使用的是scala的型別推導能力,它能讓scala自動理解你省略的型別。第二種定義方式是定義變數時並指定型別,變數名和型別之間用冒號隔開。第三種定義方式是簡化型別的方式。

注意:

對於val宣告的變數,重新賦值時,編譯器將會報錯。


var宣告的變數,重新賦值時,則不會存在問題。


3) 函式定義


def函式定義開始,max函式名,x:Inty:Int為函式引數名和型別,第三個Int表示函式返回值的型別,=號後面表示函式方法體。

對於函式返回值型別可以通過型別推導得到的可以不寫返回值型別,並且方法體只有一句程式碼的時候可以省略花括號,類似於:


一旦函式定義完成後,就可以通過函式名呼叫該方法。


定義一個既不帶引數又不帶返回結果的方法。


其中greet是方法名,空白的括號表示方法不帶引數,Unitgreet的結果型別,指的是函式沒有有效的返回值,scalaUnit型別類似於javavoid型別,而實際上

javavoid型別被對映為scala中的Unit型別。

4) 編寫scala指令碼

建立一個名為hello.scala的檔案,檔案內容為:

println("hello world, from a script!")

然後命令列執行,執行結果為:


5) whileforeachfor

(1)在指令碼中使用while迴圈,並用if判斷

建立while.scala檔案,檔案內容為:

var i = 0

while(i < args.length){

if(i != 0)

print(" ")

print(args(i))

i += 1

}

執行命令,輸出結果為:


(2)在指令碼中使用foreach

for迴圈

建立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的物件。