Scala編程的基礎(chǔ)知識(shí)

Scala是一個(gè)面向?qū)ο蟮暮瘮?shù)式編程語言,在Scala中谈截,一切皆函數(shù)。

函數(shù)式編程的優(yōu)點(diǎn):

  • 提高生產(chǎn)效率涧偷,代碼量更小簸喂。
  • 更容易編寫多并發(fā)或多進(jìn)程的應(yīng)用。
  • 帶來更少的bug燎潮,代碼量小了喻鳄,bug自然就小了。

Scala是一門基于JVM的靜態(tài)語言确封,和Java能夠無縫隙操作除呵。盡管Scala是一門混合了面向?qū)ο缶幊毯秃瘮?shù)式編程的語言唉锌,但是它還是側(cè)重于函數(shù)式編程。

Scala的安裝

由于Scala是基于JVM的靜態(tài)語言竿奏,所以安裝Scala之前需要安裝Java環(huán)境。安裝步驟可以參考 【菜鳥教程】的鏈接:http://www.runoob.com/scala/scala-install.html

基礎(chǔ)類型


這是要注意腥放,Scala并沒有基本數(shù)據(jù)類型泛啸,Scala的每一個(gè)基礎(chǔ)類型都是一個(gè)類。在編譯階段秃症,Scala編譯器會(huì)自動(dòng)將Scala基礎(chǔ)類型轉(zhuǎn)換為Java基本類型候址。

關(guān)鍵:Scala的基礎(chǔ)類型的首字母都是大寫的,如果寫成小寫會(huì)出現(xiàn)編譯錯(cuò)誤种柑,這真是一個(gè)奇葩的特點(diǎn)岗仑。

變量

Scala有兩種類型的變量:

  • 可變變量,使用var定義聚请。
  • 不可變變量荠雕,使用val定義。

可變變量可以多次賦值:

var a=20
a=10

而不可變變量驶赏,初始化后不能再重新賦值:

val b=10

對(duì)于函數(shù)式編程炸卑,最好不要使用可變變量。

函數(shù)

在Scala中煤傍,函數(shù)和變量沒有什么區(qū)別盖文,它可以作為變量的值,可以在其他函數(shù)體中定義蚯姆,可以作為函數(shù)的返回值五续,可以作為函數(shù)的參數(shù)。

Scala中用關(guān)鍵字def來定義函數(shù)龄恋。

def add(a:Int, b:Int): Int={
      val sum=a+b
      return sum
}

add是函數(shù)名疙驾;括號(hào)中的ab是形參,Int是形參類型篙挽;括號(hào)外的lnt是函數(shù)返回值類型荆萤;接著一個(gè)=號(hào)跟著大括號(hào)是函數(shù)體。

Scala中每條語句可以由分號(hào);結(jié)尾铣卡,也可以不寫链韭,當(dāng)然不寫是最方便的,怎么方便怎么來煮落。

方法

方法是指類的成員函數(shù)敞峭,這一點(diǎn)和c++/Java類似。

局部函數(shù)

在其他函數(shù)或者方法中定義的函數(shù)稱為局部函數(shù)蝉仇,它只在其定義的函數(shù)內(nèi)可見旋讹,即只有局部可見性殖蚕。

高階方法

把函數(shù)作為輸入?yún)?shù)的方法稱為高階方法。類似的沉迹,高階函數(shù)是指把函數(shù)作為參數(shù)的函數(shù)睦疫。

一個(gè)高階函數(shù)的例子:

def encode(n: Int, f:(Int) => Long): Long ={
      val x=n*10
      f(x)
}

函數(shù)encode接收兩個(gè)參數(shù),返回一個(gè)Long類型的值鞭呕。一個(gè)參數(shù)是Int類型蛤育;另一個(gè)參數(shù)是函數(shù)f函數(shù)f接收一個(gè)Int類型的參數(shù)葫松,返回的是Long類型的值

函數(shù)字面量

函數(shù)字面量是指源代碼中的匿名函數(shù)瓦糕,它可以作為高階方法或高階函數(shù)的參數(shù),也可以賦值給變量腋么。

函數(shù)字面量的定義由處于圓括號(hào)中的輸入函數(shù)列表咕娄、右箭頭和函數(shù)體構(gòu)成,下面是一個(gè)函數(shù)字面量的例子:

(x: Int) => {
      x+100
}

閉包

閉包就是可以使用非局部變量的函數(shù)字面量珊擂。

類是面向?qū)ο缶幊痰闹匾拍钍ダ眨且唤M具有相同屬性和行為的事物的抽象。Scala中的類和Java類似未玻,它由字段和方法組成灾而,字段就是屬性,方法就是行為函數(shù)扳剿。

Scala使用關(guān)鍵字class來定義一個(gè)類旁趟, 在Scala中的類沒有訪問控制這種操作,更為簡(jiǎn)潔:

class Car(mk: String, ml: String, cr: String){
    val make=mk  
    val model=ml  
    var color=cr  
    def repaint(newColor: String) = {  
        color=newColor
    }
}

類的實(shí)例使用關(guān)鍵字new創(chuàng)建

val mustang=new Car("Ford", "Mustang", "Red")

因?yàn)镾cala運(yùn)行在JVM之上庇绽,所以不用顯示刪除對(duì)象锡搜,Java的垃圾回收器會(huì)自動(dòng)刪除那些不再使用的對(duì)象。

單例

在面向?qū)ο缶幊讨幸粋€(gè)常見的設(shè)計(jì)模式就是單例瞧掺,它是指那些只可以實(shí)例化一次的類耕餐。Scala中使用關(guān)鍵字object來定義單例對(duì)象

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)

對(duì)于樣本類辟狈,Scala提供了一些語法上的便利

  • 不必使用關(guān)鍵字new就可以創(chuàng)建樣本類的實(shí)例
  • 樣本類參數(shù)列表中的所有參數(shù)隱式獲得val前綴
  • 支持模式匹配

模式匹配

模式匹配是Scala中的概念肠缔,它類似于其他語言的switch語句『咦考慮一個(gè)以顏色的字符串作為參數(shù)的簡(jiǎn)單函數(shù):

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
}

模式匹配的幾個(gè)特性:

  • Scala使用關(guān)鍵字match代替關(guān)鍵字switch明未。
  • 下劃線代表默認(rèn)選項(xiàng)。
  • 每一個(gè)選項(xiàng)不需要break語句壹蔓,匹配選項(xiàng)后趟妥,其他的選項(xiàng)不會(huì)被執(zhí)行。
  • 每一個(gè)選項(xiàng)對(duì)應(yīng)一個(gè)表達(dá)式佣蓉,每個(gè)表達(dá)式返回一個(gè)值披摄。

操作符

Scala沒有內(nèi)置操作符亲雪,在Scala中,每個(gè)基礎(chǔ)類型都是一個(gè)類疚膊,每一個(gè)操作符都是一個(gè)方法义辕。使用操作符等價(jià)于調(diào)用方法。例如:

val a=10
val b=20
val c=a+b 

這里的并不是Scala的內(nèi)置操作符寓盗,它是定義在Int類中的一個(gè)方法终息。Scala允許以操作符的方式來調(diào)用方法。

特征

Scala的特征類似于Java中的接口贞让,然而,不同于Java接口柳譬,Scala的特征可以有方法的實(shí)現(xiàn)喳张,而且它還可以有字段。

特征看上去像抽象類美澳,它們都有字段和方法销部。區(qū)別在于一個(gè)類只能繼承一個(gè)抽象類,但可以繼承多個(gè)特征制跟。

Scala中的特征使用關(guān)鍵字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

元組

元組是一個(gè)容器舅桩,用于存放多個(gè)不同類型的元素,它是不可變的雨膨。即創(chuàng)建元組之后擂涛,便不可修改。

元組是一個(gè)用小括號(hào)括起來的大雜燴:

val a=(10, true, "harry")

元組的下標(biāo)從1開始的聊记,訪問元組的元素如下:

println(a._1)
println(a._2)

為什么下標(biāo)數(shù)字前面有一個(gè)礙眼的下劃線撒妈??鬼知道這種騷操作是為何排监。反正沒下劃線就會(huì)報(bào)錯(cuò)~

Option類型

Option是一種數(shù)據(jù)類型狰右,用來表示值是可選的,即要么無值要么有值舆床。它要么是樣本類some的實(shí)例棋蚌,要么是單例對(duì)象None的實(shí)例。

Option類型可以在函數(shù)或方法中作為值返回挨队。返回some(x)表示有值谷暮,返回None表示無值。從函數(shù)返回的Option類型對(duì)象可以用于模式匹配中:

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類型有助于避免空指針異常瞒瘸。

集合

集合是一種容器類的數(shù)據(jù)結(jié)構(gòu)坷备。Scala有豐富的集合類,集合類包含各種類型情臭,所有的集合類都有同樣的接口省撑。

Scala的集合類可以分為三類:

  • 序列
  • 集合
  • map

序列

序列表示有先后次序的元素序列赌蔑,可根據(jù)位置來訪問集合中的元素。
序列又分為三種:

  • 數(shù)組
  • 列表
  • 向量
數(shù)組Array

數(shù)組是有索引的元素序列竟秫,所有的元素的數(shù)據(jù)類型相同娃惯,數(shù)組是可變的,可以修改元素但不能增加元素肥败,即數(shù)組是定長(zhǎng)的趾浅。

Scala中的數(shù)組類似于其他語言的數(shù)組,數(shù)組索引從0開始馒稍,通過索引訪問或修改元素:

val arr = Array(10, 20, 30 ,40)
println(arr(0))
列表List

列表是一個(gè)線性的元素序列皿哨,存放一堆數(shù)據(jù)類型相同的元素,列表是不可變的纽谒,即創(chuàng)建后不可修改证膨。

創(chuàng)建列表的幾種方法:

val a=List(10, 20, 30)
val b=(1 to 100).toList
val c=someArray.toList

關(guān)于列表的幾種操作:

  • 訪問第一個(gè)元素使用head方法
  • 訪問第一個(gè)元素之后的所有元素使用tail方法鼓黔。
  • 判斷列表是否為空央勒,使用isEmpty方法。當(dāng)列表為空時(shí)返回true
向量Vector

向量是結(jié)合了列表和數(shù)組的優(yōu)點(diǎn)的類澳化,根據(jù)索引訪問元素占用固定的時(shí)間崔步。向量支持快速修改和訪問任意位置的元素:

val v1 = Vector(0, 10, 20, 30)
val v2 = v1 :+ 50  // 在向量末尾添加元素50
val v3 = v1(3)

集合Set

集合是一個(gè)無序的集合,且每個(gè)元素都不同缎谷,沒用索引井濒。

val f = Set(1, 2, 3 ) 

集合支持兩種基本操作:

  • contains: 如果集合中包含這個(gè)元素,則返回true列林,并將這個(gè)元素作為參數(shù)傳遞過來
  • isEmpty: 如果當(dāng)前集合為空眼虱,則返回true

map

map是一個(gè)鍵-值對(duì)集合,在其他語言中席纽,map也叫做字典捏悬。即根據(jù)鍵找出相應(yīng)的值。

val a = Map("USA" -> "zhazha", "UK" -> "London", "India" -> "New Delhi")
val indiaCapital = a("India")

注意:Scala的各種集合類都是使用小括號(hào)润梯,沒有中括號(hào)和大括號(hào)过牙!

集合類上的高階方法

Scala集合的強(qiáng)大之處就在于這些高階方法,這些高階方法把函數(shù)當(dāng)做參數(shù)纺铭。

map方法

map方法的參數(shù)是一個(gè)函數(shù)寇钉,它將這個(gè)函數(shù)作用于集合中的每一個(gè)元素,返回由其返回值所組成的集合舶赔。

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扫倡,它的參數(shù)是一個(gè)函數(shù),它把這個(gè)函數(shù)作用于集合中的每一個(gè)元素竟纳,返回另外一個(gè)集合撵溃。

val line = "Scala is fun"
val SingleSpace = " "
val words = line.split(SingleSpace)
val array = words.flatMap(_.toList)
array

輸出結(jié)果為:

scala> array
res4: Array[Char] = Array(S, c, a, l, a, i, s, f, u, n)

Scala版的hello world

一個(gè)單獨(dú)的Scala應(yīng)用程序需要一個(gè)具有main方法的單例對(duì)象疚鲤。這個(gè)main方法以一個(gè)Array[String]類型的參數(shù)作為輸入,它不需要返回值缘挑,它是這個(gè)Scala程序的入口集歇,這個(gè)有main方法的單例可以隨便起名。

object HelloWorld{
    /*
    這是我的第一個(gè)Scala程序
    */
    def main(args: Array[String]){
        println("hello world!") // 輸出hello world
    }
 }

Scala源代碼文件以.scala作為后綴名语淘,依照慣例诲宇,一般以代碼中的賴明或者單例名作為文件名,比如上面的代碼文件應(yīng)該命名為HelloWorld.scala惶翻。

這篇文章寫了一天姑蓝,終于寫完了。

每天學(xué)習(xí)一點(diǎn)點(diǎn)吕粗,每天進(jìn)步一點(diǎn)點(diǎn)它掂。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市溯泣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌榕茧,老刑警劉巖垃沦,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異用押,居然都是意外死亡肢簿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門蜻拨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來池充,“玉大人,你說我怎么就攤上這事缎讼∈湛洌” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵血崭,是天一觀的道長(zhǎng)卧惜。 經(jīng)常有香客問我,道長(zhǎng)夹纫,這世上最難降的妖魔是什么咽瓷? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮舰讹,結(jié)果婚禮上茅姜,老公的妹妹穿的比我還像新娘。我一直安慰自己月匣,他們只是感情好钻洒,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布奋姿。 她就那樣靜靜地躺著,像睡著了一般航唆。 火紅的嫁衣襯著肌膚如雪胀蛮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天糯钙,我揣著相機(jī)與錄音粪狼,去河邊找鬼。 笑死任岸,一個(gè)胖子當(dāng)著我的面吹牛再榄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播享潜,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼困鸥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了剑按?” 一聲冷哼從身側(cè)響起疾就,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎艺蝴,沒想到半個(gè)月后猬腰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡猜敢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年姑荷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缩擂。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鼠冕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出胯盯,到底是詐尸還是另有隱情懈费,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布博脑,位于F島的核電站楞捂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏趋厉。R本人自食惡果不足惜寨闹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望君账。 院中可真熱鬧繁堡,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至绳矩,卻和暖如春袭厂,著一層夾襖步出監(jiān)牢的瞬間拌消,已是汗流浹背唐全。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工启具, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人应媚。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓严沥,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親中姜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子消玄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容