Scala程式設計的基礎知識
Scala是一個面向物件的函數語言程式設計語言,在Scala中,一切皆函式。
函數語言程式設計的優點:
- 提高生產效率,程式碼量更小。
- 更容易編寫多併發或多程序的應用。
- 帶來更少的bug,程式碼量小了,bug自然就小了。
Scala是一門基於JVM的靜態語言,和Java能夠無縫隙操作。儘管Scala是一門混合了面向物件程式設計和函數語言程式設計的語言,但是它還是側重於函數語言程式設計。
Scala的安裝
由於Scala是基於JVM的靜態語言,所以安裝Scala之前需要安裝Java環境。安裝步驟可以參考 【菜鳥教程】的連結: http://www.runoob.com/scala/scala-install.html
基礎型別

這是要注意,Scala並沒有基本資料型別,Scala的每一個基礎型別都是一個類。在編譯階段,Scala編譯器會自動將Scala基礎型別轉換為Java基本型別。
關鍵:Scala的基礎型別的首字母都是大寫的,如果寫成小寫會出現編譯錯誤,這真是一個奇葩的特點。
變數
Scala有兩種型別的變數:
var val
可變變數可以多次賦值:
var a=20 a=10
而不可變變數,初始化後不能再重新賦值:
val b=10
對於函數語言程式設計,最好不要使用可變變數。
函式
在Scala中,函式和變數沒有什麼區別,它可以作為變數的值,可以在其他函式體中定義,可以作為函式的返回值,可以作為函式的引數。
Scala中用關鍵字 def
來定義函式。
def add(a:Int, b:Int): Int={ val sum=a+b return sum }
add
是函式名;括號中的 a
和 b
是形參, Int
是形參型別;括號外的 lnt
是函式返回值型別;接著一個 =
號跟著大括號是函式體。
Scala中每條語句可以由分號 ;
結尾,也可以不寫,當然不寫是最方便的,怎麼方便怎麼來。
方法
方法是指類的成員函式,這一點和c++/Java類似。
區域性函式
在其他函式或者方法中定義的函式稱為區域性函式,它只在其定義的函式內可見,即只有區域性可見性。
高階方法
把函式作為輸入引數的方法稱為高階方法。類似的,高階函式是指把函式作為引數的函式。
一個高階函式的例子:
def encode(n: Int, f:(Int) => Long): Long ={ val x=n*10 f(x) }
函式encode
接收兩個引數,返回一個 Long型別
的值。一個引數是 Int
型別;另一個引數是 函式f
, 函式f
接收一個 Int型別
的引數,返回的是 Long型別
的值
函式字面量
函式字面量是指原始碼中的匿名函式,它可以作為高階方法或高階函式的引數,也可以賦值給變數。
函式字面量的定義由處於圓括號中的輸入函式列表、右箭頭和函式體構成,下面是一個函式字面量的例子:
(x: Int) => { x+100 }
閉包
閉包就是可以使用非區域性變數的函式字面量。
類
類是面向物件程式設計的重要概念,是一組具有相同屬性和行為的事物的抽象。Scala中的類和Java類似,它由欄位和方法組成,欄位就是屬性,方法就是行為函式。
Scala使用關鍵字 class
來定義一個類, 在Scala中的類沒有訪問控制這種操作,更為簡潔:
class Car(mk: String, ml: String, cr: String){ val make=mk val model=ml var color=cr def repaint(newColor: String) = { color=newColor } }
類的例項使用關鍵字 new
建立
val mustang=new Car("Ford", "Mustang", "Red")
因為Scala執行在JVM之上,所以不用顯示刪除物件,Java的垃圾回收器會自動刪除那些不再使用的物件。
單例
在面向物件程式設計中一個常見的設計模式就是單例,它是指那些 只可以例項化一次的類 。Scala中使用關鍵字 object
來定義單例物件
object DatabaseConnection{ def open(name: String) : Int ={ ... } def read(streamId: Int) : Array[Byte] = { ... } def close(): Unit={ ... } }
樣本類
樣本類是指使用 case
修飾符的類,例如:
case class Message(from: String, to: String, content: String)
對於樣本類,Scala提供了一些語法上的便利
new val
模式匹配
模式匹配是Scala中的概念,它類似於其他語言的 switch語句
。考慮一個以顏色的字串作為引數的簡單函式:
def colorToNumber(color: String): Int ={ val num=color match{ case "Red" => 1 case "Blue"=> 2 case "Green"=> 3 case "Yellow" => 4 case _ =>0 } return num }
模式匹配的幾個特性:
- Scala使用關鍵字
match
代替關鍵字switch
。 - 下劃線代表預設選項。
- 每一個選項不需要
break語句
,匹配選項後,其他的選項不會被執行。 - 每一個選項對應一個表示式,每個表示式返回一個值。
操作符
Scala沒有內建操作符,在Scala中,每個基礎型別都是一個類,每一個操作符都是一個方法。使用操作符等價於呼叫方法。例如:
val a=10 val b=20 val c=a+b
這裡的 +
並不是Scala的內建操作符,它是定義在 Int
類中的一個方法。Scala允許以操作符的方式來呼叫方法。
特徵
Scala的特徵類似於Java中的介面,然而,不同於Java介面,Scala的特徵可以有方法的實現,而且它還可以有欄位。
特徵看上去像抽象類,它們都有欄位和方法。區別在於一個類只能繼承一個抽象類,但可以繼承多個特徵。
Scala中的特徵使用關鍵字 trait
定義:
trait Shape{ def area(): Int } class Square(length: Int) extends Shape{ def area=length*length } class Rectangle(length: Int, width: Int) extends Shape{ def area=length*width } val square = new Square(10) val area = square.area
元組
元組是一個容器,用於存放多個不同型別的元素,它是不可變的。即建立元組之後,便不可修改。
元組是一個用小括號括起來的大雜燴:
val a=(10, true, "harry")
元組的下標從1開始的,訪問元組的元素如下:
println(a._1) println(a._2)
為什麼下標數字前面有一個礙眼的下劃線??鬼知道這種騷操作是為何。反正沒下劃線就會報錯~
Option型別
Option是一種資料型別,用來表示值是可選的,即要麼無值要麼有值。它要麼是樣本類 some
的例項,要麼是單例物件 None
的例項。
Option型別可以在函式或方法中作為值返回。返回 some(x)
表示有值,返回 None
表示無值。從函式返回的Option型別物件可以用於模式匹配中:
def colorCode(color: String): Option[Int] ={ color match{ case "Red" => Some(1) case "Blue"=> Some(2) case "Green"=> Some(3) case "Yellow" => Some(4) case _ => None } } val code = colorCode("orange") code match{ case Some(c) => println("code for orange is: " + c) case None => println("code not defined for orange") }
使用Option型別有助於避免空指標異常。
集合
集合是一種容器類的資料結構。Scala有豐富的集合類,集合類包含各種型別,所有的集合類都有同樣的介面。
Scala的集合類可以分為三類:
- 序列
- 集合
- map
序列
序列表示有先後次序的元素序列,可根據位置來訪問集合中的元素。
序列又分為三種:
- 陣列
- 列表
- 向量
陣列Array
陣列是有索引的元素序列,所有的元素的資料型別相同,陣列是可變的,可以修改元素但不能增加元素,即陣列是定長的。
Scala中的陣列類似於其他語言的陣列,陣列索引從0開始,通過索引訪問或修改元素:
val arr = Array(10, 20, 30 ,40) println(arr(0))
列表List
列表是一個線性的元素序列,存放一堆資料型別相同的元素,列表是不可變的,即建立後不可修改。
建立列表的幾種方法:
val a=List(10, 20, 30) val b=(1 to 100).toList val c=someArray.toList
關於列表的幾種操作:
- 訪問第一個元素使用
head方法
。 - 訪問第一個元素之後的所有元素使用
tail方法
。 - 判斷列表是否為空,使用
isEmpty方法
。當列表為空時返回true
向量Vector
向量是結合了列表和陣列的優點的類,根據索引訪問元素佔用固定的時間。向量支援快速修改和訪問任意位置的元素:
val v1 = Vector(0, 10, 20, 30) val v2 = v1 :+ 50// 在向量末尾新增元素50 val v3 = v1(3)
集合Set
集合是一個無序的集合,且每個元素都不同,沒用索引。
val f = Set(1, 2, 3 )
集合支援兩種基本操作:
-
contains
: 如果集合中包含這個元素,則返回true
,並將這個元素作為引數傳遞過來 -
isEmpty
: 如果當前集合為空,則返回true
map
map是一個鍵-值對集合,在其他語言中,map也叫做字典。即根據鍵找出相應的值。
val a = Map("USA" -> "zhazha", "UK" -> "London", "India" -> "New Delhi") val indiaCapital = a("India")
注意:Scala的各種集合類都是使用小括號,沒有中括號和大括號!
集合類上的高階方法
Scala集合的強大之處就在於這些高階方法,這些高階方法把函式當做引數。
map方法
map方法的引數是一個函式,它將這個函式作用於集合中的每一個元素,返回由其返回值所組成的集合。
val xs = List(1, 2, 3, 4) val ys = xs.map((x: Int) => x*10.0) println(ys)
輸出如下:
scala> println(ys) List(10.0, 20.0, 30.0, 40.0)
flatMap
Scala集合的flatMap方法類似於map,它的引數是一個函式,它把這個函式作用於集合中的每一個元素,返回另外一個集合。
val line = "Scala is fun" val SingleSpace = " " val words = line.split(SingleSpace) val array = words.flatMap(_.toList) array
輸出結果為:
scala> array res4: Array[Char] = Array(S, c, a, l, a, i, s, f, u, n)
Scala版的hello world
一個單獨的Scala應用程式需要一個具有 main方法
的單例物件。這個 main方法
以一個 Array[String]
型別的引數作為輸入,它不需要返回值,它是這個Scala程式的入口,這個有 main方法
的單例可以隨便起名。
object HelloWorld{ /* 這是我的第一個Scala程式 */ def main(args: Array[String]){ println("hello world!") // 輸出hello world } }
Scala原始碼檔案以 .scala
作為字尾名,依照慣例,一般以程式碼中的賴明或者單例名作為檔名,比如上面的程式碼檔案應該命名為 HelloWorld.scala
。
這篇文章寫了一天,終於寫完了。
每天學習一點點,每天進步一點點。