Scala 摘要

讀《快學(xué)Scala 》一書(shū)的摘要

Scala 運(yùn)行于JVM之上,擁有海量類(lèi)庫(kù)和工具镊讼,兼顧函數(shù)式編程和面向?qū)ο蟆?/p>

在Scala中宽涌, 解釋器就是我們喜歡的REPL,變量或者函數(shù)的類(lèi)型總是寫(xiě)在變量或函數(shù)的后面(與java相反)蝶棋,數(shù)值類(lèi)型的轉(zhuǎn)換通過(guò)方法而不是強(qiáng)制類(lèi)型轉(zhuǎn)換卸亮,僅當(dāng)同一行代碼存在多條語(yǔ)句時(shí)才需要用分號(hào)隔開(kāi)。

scala 允許自定義操作符玩裙,注意有分寸地使用兼贸,在使用scala.開(kāi)頭的包時(shí),可以省去scala前綴吃溅。scala沒(méi)有靜態(tài)方法溶诞,類(lèi)似的特性可以用單例對(duì)象,一個(gè)類(lèi)對(duì)應(yīng)的companion object就跟Java中的靜態(tài)方法一樣罕偎,使用companion object的apply方法是scala中構(gòu)建對(duì)象的常用方法很澄。

控制

在scala中,判斷語(yǔ)句跟其他語(yǔ)言類(lèi)似颜及,但{}塊包含一系列表達(dá)式甩苛,其結(jié)果也是一個(gè)表達(dá)式,塊中最后一個(gè)表達(dá)式的值就是塊的值俏站。

在for 循環(huán)的變量之前并沒(méi)有val或var的指定讯蒲。該變量的類(lèi)型是集合的元素類(lèi)型,循環(huán)變量的作用域一直持續(xù)到循環(huán)結(jié)束肄扎。scala并沒(méi)有提供break或continue語(yǔ)句來(lái)退出循環(huán)墨林,替代方法如下:

  1. 使用Boolean的控制變量
  2. 使用嵌套函數(shù)——在函數(shù)中return
  3. 使用Breaks對(duì)象中的break方法赁酝,控制權(quán)的轉(zhuǎn)移是通過(guò)拋出和捕獲異常完成的,出于性能考慮旭等,盡量避免這一機(jī)制酌呆。

for有豐富的形態(tài),可以提供多個(gè)生成器搔耕,并帶有if開(kāi)頭的表達(dá)式隙袁,還可以使用任意多的循環(huán)變量定義。

函數(shù)

scala中的方法對(duì)對(duì)象進(jìn)行操作弃榨,而函數(shù)不是菩收,C++中也有函數(shù),不過(guò)在Java中智能用靜態(tài)方法模擬鲸睛,scala的函數(shù)不需要return娜饵,對(duì)應(yīng)遞歸函數(shù)必須指明返回類(lèi)型,可以混用未命名參數(shù)和帶名參數(shù)官辈,只要那些未命名的參數(shù)是排在前面的即可箱舞。

同樣,變長(zhǎng)參數(shù)列表很方便拳亿,通過(guò) :_* 將值序列轉(zhuǎn)換成參數(shù)序列褐缠。當(dāng)變長(zhǎng)參數(shù)類(lèi)型為Object的Java方法時(shí),需要手工對(duì)基本類(lèi)型進(jìn)行轉(zhuǎn)換风瘦。

scala對(duì)不返回值的函數(shù)有特殊的表示法,如果函數(shù)體包含在花括號(hào)當(dāng)中但沒(méi)有前面的=號(hào)公般,那么返回類(lèi)型就是Unit万搔,這樣的函數(shù)也叫過(guò)程函數(shù)。

當(dāng)val 被聲明為lazy時(shí)官帘,它的初始化將被延遲加載瞬雹,直到對(duì)它初次取值。每次訪(fǎng)問(wèn)延遲加載的變量刽虹,都會(huì)有一個(gè)方法被調(diào)用酗捌,以線(xiàn)程安全的方式檢查該值是否已被初始化。

異常

scala異常的工作機(jī)制和Java或C++一樣涌哲,但沒(méi)有"受檢"異常胖缤,捕獲異常采用模式匹配的語(yǔ)法,不需要使用捕獲的異常對(duì)象阀圾,可以用_來(lái)替代變量名哪廓。try/catch和try/finally是互補(bǔ)的。

數(shù)組和映射

Scala中的Array是定長(zhǎng)數(shù)組初烘,ArrayBuffer是變長(zhǎng)數(shù)組涡真,對(duì)應(yīng)于Java中的ArrayList分俯,C++中的Vector,可以用相同的代碼處理這兩種數(shù)據(jù)結(jié)構(gòu)哆料,用 for (i<-區(qū)間 )來(lái)遍歷缸剪,

for(...) yield 創(chuàng)建一個(gè)類(lèi)型與原始集合相同的新集合,還可以通過(guò)if 在進(jìn)行條件過(guò)濾东亦。Scala中的內(nèi)建函數(shù)sum杏节,sorted,max讥此,min拢锹,quicksork提供了常用算法。由于Scala數(shù)組是用java數(shù)組實(shí)現(xiàn)的萄喳,可以在java和scala之間傳遞卒稳,只需引入scala.collection.JavaConversions里的隱式轉(zhuǎn)換方法。

scala中他巨,映射是對(duì)偶的集合,可以看做將鍵映射到值的函數(shù)充坑,區(qū)別在于函數(shù)一般用于計(jì)算,而映射只做查詢(xún)染突。用=可以直接增加映射捻爷,也可用+=添加多個(gè)關(guān)系,用for((k,v)<-映射) 來(lái)遍歷映射份企,使用scala.collection.JavaConversions.mapAsScalaMap將Java中的map轉(zhuǎn)換為scala中的映射也榄。

scala中,元組是不同類(lèi)型的值的聚集司志,()構(gòu)成元組甜紫,用方法1,2...訪(fǎng)問(wèn)其組元,而通常使用模式匹配來(lái)獲取元組的組元骂远。使用元組的原因之一是把多個(gè)值綁在一起囚霸,以便它們能夠被一起處理,通常用zip方法開(kāi)完成激才,使用toMap方法將對(duì)偶的集合轉(zhuǎn)換成映射拓型。

類(lèi)與對(duì)象

在scala中,類(lèi)并不聲明為public瘸恼,源文件可以包含多個(gè)類(lèi)劣挫,所有這些類(lèi)都具有共有可見(jiàn)性。對(duì)每個(gè)字段都提供了getter和setter方法东帅,分別叫做 字段名 和 字段名_,可重新自定義揣云。

注意:

1)如果字段私有,則getter和setter也是私有的

2)如果字段val冰啃,則只有g(shù)etter方法

3)如果不需任何getter和setter邓夕,可將字段聲明為private[this]

將scala字段標(biāo)注為@BeanProperty時(shí)刘莹,會(huì)產(chǎn)生Java屬性的定義方法getxxx和setxxx。

scala中的類(lèi)有一個(gè)主構(gòu)造器primary constructor焚刚,可有任意多個(gè)輔助構(gòu)造器 auxiliary constructor点弯。輔助構(gòu)造器與其他語(yǔ)言的區(qū)別在于: 1)名稱(chēng)為this 2)必須以一個(gè)先前已定義的其他輔助構(gòu)造器或主構(gòu)造器的調(diào)用開(kāi)始。而主構(gòu)造器的參數(shù)直接放置在類(lèi)名之后矿咕,會(huì)執(zhí)行類(lèi)定義中的所有語(yǔ)句抢肛,無(wú)參主構(gòu)造器僅僅執(zhí)行類(lèi)體中的所有語(yǔ)句而已。如果將主構(gòu)造器定義為私有的碳柱,則必須通過(guò)輔助構(gòu)造器來(lái)構(gòu)造對(duì)象了捡絮。在內(nèi)嵌類(lèi)中,可以通過(guò)外部類(lèi).this來(lái)訪(fǎng)問(wèn)外部類(lèi)的this 引用莲镣。

對(duì)象本質(zhì)上擁有類(lèi)的所有特質(zhì)福稳,只不能提供構(gòu)造器參數(shù)。所有使用單例對(duì)象的地方瑞侮,scala中都可以用對(duì)象來(lái)實(shí)現(xiàn)的圆。

1)作為存放工具函數(shù)或常量的地方

2)高效共享單個(gè)不可變實(shí)例

3)需要用單個(gè)實(shí)例來(lái)協(xié)調(diào)某個(gè)服務(wù)時(shí)

對(duì)Java中既有實(shí)例方法又有靜態(tài)方法的類(lèi),scala通過(guò)類(lèi)及與類(lèi)同名的伴生對(duì)象來(lái)實(shí)現(xiàn)半火。類(lèi)和它的伴生對(duì)象可以相互訪(fǎng)問(wèn)私有特性越妈,必須存在于同一源文件中。

每個(gè)scala程序都必須從一個(gè)對(duì)象的main方法開(kāi)始钮糖,也可以擴(kuò)展App特質(zhì)梅掠。scala中沒(méi)有枚舉類(lèi)型,但標(biāo)準(zhǔn)類(lèi)庫(kù)提供了一個(gè)Enumeration助手類(lèi)店归,用于產(chǎn)生枚舉瓤檐。

Scala中的包與java包或c++命名空間的目的相同,但可以在同一文件中為多個(gè)包貢獻(xiàn)內(nèi)容娱节。

盡量使用完整包名,避免使用scala,java,com,org等來(lái)命名嵌套的包祭示。串聯(lián)式包語(yǔ)句可以限定可見(jiàn)的包肄满。

包可以包含類(lèi),對(duì)象和屬性质涛,但不能包含函數(shù)和變量的定義稠歉,在實(shí)現(xiàn)上,包對(duì)象被編譯成帶有靜態(tài)方法和字段的JvM類(lèi)汇陆。通過(guò)修飾符同樣可以達(dá)到public怒炸,private或protected的效果。

在scala中毡代, 任何地方都可以聲明引入包阅羹,這一點(diǎn)和python很相似勺疼。通過(guò)選取器可以引入包中的指定成員,還可以對(duì)指定成員重命名或者隱藏java.lang,scala,predef 總是被默認(rèn)引入的捏鱼。

繼承

scala擴(kuò)展類(lèi)的方式同樣是使用extends關(guān)鍵字执庐,重寫(xiě)一個(gè)非抽象方法必須使用override修飾符,用isInstanceOf方法判斷某個(gè)對(duì)象是否屬于某個(gè)特定的類(lèi)导梆,只有主構(gòu)造器可以調(diào)用超類(lèi)的構(gòu)造器轨淌。

字段重寫(xiě)時(shí)的限制:

  • def 只能重寫(xiě)另一個(gè)def
  • 只能重寫(xiě)另一個(gè)val或不帶參數(shù)的def
  • var只能重寫(xiě)另一個(gè)抽象的var

構(gòu)造順序問(wèn)題的根本原因——java允許在超類(lèi)的構(gòu)造方法中調(diào)用子類(lèi)的方法。因?yàn)樵谧宇?lèi)中正確的擴(kuò)展相等性判斷非常困難看尼,所以將equals方法定義成final递鹉。除非萬(wàn)不得已,不要使用wait藏斩,notify和synchronized躏结。

和java的接口不同,scala特質(zhì)可以給出這些特質(zhì)的缺省實(shí)現(xiàn)灾茁。讓特質(zhì)擁有具體行為存在一個(gè)弊端窜觉,當(dāng)特質(zhì)改變時(shí),所有混入了該特質(zhì)的類(lèi)必須要重新編譯北专。scala不支持多繼承禀挫,可以用with關(guān)鍵字來(lái)添加額外的特質(zhì)。當(dāng)做富接口使用的特質(zhì)將具體方法和抽象方法結(jié)合在了一起拓颓,特質(zhì)中的字段同樣既可以是具體的语婴,又可以是抽象的。

混入特質(zhì)的對(duì)象在構(gòu)造時(shí)的執(zhí)行順序:

  1. 首先調(diào)用超類(lèi)的構(gòu)造器
  2. 特質(zhì)構(gòu)造器在超類(lèi)構(gòu)造器之后驶睦,類(lèi)構(gòu)造器之前執(zhí)行
  3. 特質(zhì)由左到右構(gòu)造
  4. 每個(gè)特質(zhì)中砰左,父特質(zhì)先被構(gòu)造,
  5. 如果多個(gè)特質(zhì)有一個(gè)父特質(zhì)场航,若已被構(gòu)造則不會(huì)再次構(gòu)造
  6. 所有特質(zhì)構(gòu)造完畢缠导,子類(lèi)被構(gòu)造。

缺少構(gòu)造器參數(shù)是特質(zhì)與類(lèi)之間唯一的技術(shù)差別溉痢。

文件訪(fǎng)問(wèn)

scala.io.source對(duì)象的getlines方法可以讀取文件的所有行僻造,可以把source對(duì)象當(dāng)成迭代器讀取文件中的每個(gè)字符,java.util.Scanner來(lái)處理同事包含文本和數(shù)字的文件孩饼。

從URL中讀取時(shí)髓削,需要事先知道編碼格式,scala中沒(méi)有提供讀取二進(jìn)制文件的方法镀娶,需要使用Java類(lèi)庫(kù),同樣沒(méi)有內(nèi)建的對(duì)寫(xiě)入文件的支持立膛,可使用java.io.PrintWriter,訪(fǎng)問(wèn)目錄也要用java的方法,例如java.nio.file.Files類(lèi)中的walkFileTree梯码。

scala集合類(lèi)都是可序列化的宝泵。

scala.sys.process包提供了用于與shell程序交互的工具好啰,包含了一個(gè)從字符串到processbuilder對(duì)象的隱式轉(zhuǎn)換,鲁猩!操作符就是執(zhí)行這個(gè)processbuidler的對(duì)象坎怪。scala.util.matching.Regex 利用正則表達(dá)式對(duì)字符串進(jìn)行分析。

操作符與解析器

變量廓握、函數(shù)搅窿、類(lèi)等的名稱(chēng)統(tǒng)稱(chēng)為標(biāo)識(shí)符,反引號(hào)中可以包含幾乎任何字符序列隙券。
在scala中男应,除了

  • 以冒號(hào):結(jié)尾的操作符
  • 賦值操作符
    所有操作符都是左結(jié)合的。

unapply方法接受一個(gè)對(duì)象娱仔,然后從中取值沐飘,通常是當(dāng)初用來(lái)構(gòu)造該對(duì)象的值。要取任意長(zhǎng)度的值的序列牲迫,一般用unapplySeq命名方法耐朴。

Scala解析器庫(kù)是scala語(yǔ)言總內(nèi)嵌領(lǐng)域特定語(yǔ)言(DSL)的高級(jí)示例。為了使用Scala解析庫(kù)盹憎,需提供一個(gè)擴(kuò)展自Parsers特質(zhì)的類(lèi)并定義那些由基本操作組合起來(lái)的解析操作筛峭,包括:

  1. 匹配一個(gè)詞法單元
  2. 在兩個(gè)操作之間做選擇(|)
  3. 依次執(zhí)行兩個(gè)操作(~)
  4. 重復(fù)一個(gè)操作(rep)
  5. 可選擇地執(zhí)行一個(gè)操作(opt)

組合子返回的是樣例類(lèi)的實(shí)例而不是對(duì)偶,這樣更方便模式匹配陪每。要生成解析樹(shù)影晓,需用^^操作符,給出產(chǎn)生樹(shù)節(jié)點(diǎn)的函數(shù)檩禾,避免左遞歸和回溯挂签。

StandardTokenParsers類(lèi)提供了一個(gè)產(chǎn)出這些詞法單元的解析器。

集合

Scala中所有集合都是iterable的盼产,seq是有先后次序的序列(如數(shù)組和列表)饵婆,Set是沒(méi)有先后次序的序列,map是一種鍵值對(duì)偶戏售。Scala優(yōu)先采用不可變集合侨核,::操作符從給定的頭和尾創(chuàng)建一個(gè)新的列表。如果要把列表中的某個(gè)節(jié)點(diǎn)變成列表中的最后一個(gè)節(jié)點(diǎn)蜈项,不能將next引用設(shè)為nil,而應(yīng)該設(shè)為L(zhǎng)inkedList.empty.

已排序的集使用紅黑樹(shù)實(shí)現(xiàn)的续挟,scala2.9沒(méi)有可變的已排序集紧卒,要用到j(luò)ava.util.TreeSet

Scala 關(guān)于添加和移除的操作符:

  1. 向后(:+)或向前(+:)追加元素到序列中
  2. 添加(+)元素到無(wú)先后次序的集合中
  3. -移除元素
  4. ++--批量添加和移除元素
  5. 對(duì)于列表,優(yōu)先使用:::::
  6. 改值操作有+=诗祸,++=跑芳,-=--=

對(duì)于集合轴总,推薦++,&和--博个,盡量不用++:怀樟,+=:和++=: 操作方式。

初始值和操作符是兩個(gè)分開(kāi)定義的柯里化參數(shù)盆佣,這樣scala就能用初始值類(lèi)型來(lái)推斷操作符的類(lèi)型定義往堡。任何while循環(huán)都可以用折疊來(lái)替代,對(duì)于那些完整構(gòu)造需要很大開(kāi)銷(xiāo)的集合而言共耍,迭代器作用大虑灰,而流將緩存訪(fǎng)問(wèn)過(guò)的行,允許你重新訪(fǎng)問(wèn)他們痹兜。

對(duì)于數(shù)組穆咐,緩存,哈希表字旭,平衡樹(shù)而言对湃,基于par方法的并行實(shí)現(xiàn)很高效。

模式匹配

與switch語(yǔ)句不同遗淳,scala模式匹配沒(méi)有break的問(wèn)題拍柒。如果case中的判斷不能匹配,則捕獲所有的模式來(lái)嘗試匹配洲脂。變量模式可能與常量表達(dá)式?jīng)_突斤儿,變量必須以小寫(xiě)字母開(kāi)頭。如果有一個(gè)小寫(xiě)字母開(kāi)頭的常量恐锦,則需要把它抱在反引號(hào)中往果。

在類(lèi)型匹配的時(shí)候,必須給出一個(gè)變量名一铅,否則會(huì)拿對(duì)象本身來(lái)進(jìn)行匹配陕贮。由于匹配發(fā)生在運(yùn)行時(shí),Jvm中泛型的類(lèi)型信息是被擦掉的潘飘,所有不能用類(lèi)型來(lái)匹配特定的Map類(lèi)型肮之。正則表達(dá)式是適合使用提取器的場(chǎng)景。

樣例類(lèi)是一種特殊的類(lèi)卜录,經(jīng)過(guò)優(yōu)化以被用于模式匹配戈擒,其實(shí)例使用(),樣例對(duì)象不使用圓括號(hào)艰毒。中置表示法可用于任何返回對(duì)偶的unapply方法筐高。樣例類(lèi)的特點(diǎn):

  1. 模式匹配的代碼更精簡(jiǎn)
  2. 構(gòu)造時(shí)不需new
  3. 可以免費(fèi)得到toString,equals,hashCode 和copy方法

讓所有樣例類(lèi)都擴(kuò)展某個(gè)密封的類(lèi)或特質(zhì)是個(gè)好做法。被包在花括號(hào)內(nèi)的一組case語(yǔ)句是一個(gè)偏函數(shù)柑土,偏函數(shù)表達(dá)式必須位于編譯器可以推斷返回類(lèi)型的上下文中蜀肘。

注解

注解可以在程序的各個(gè)條目中添加信息,是插入到代碼中以便有工具可以對(duì)他們進(jìn)行處理的標(biāo)簽稽屏“绯瑁可以對(duì)是scala類(lèi)使用java注解,也可以使用scala特有的注解狐榔。

在scala中坛增,可為類(lèi),方法荒叼,字段轿偎,局部變量和參數(shù)添加注解。Java注解的參數(shù)類(lèi)型只能是:

  1. 數(shù)值型變量
  2. 字符串
  3. 類(lèi)變量
  4. java枚舉
  5. 其他注解
  6. 上述類(lèi)型的數(shù)組被廓。

如果要實(shí)現(xiàn)一個(gè)新的Java注解坏晦,則需要用Java來(lái)編寫(xiě)該注解類(lèi)。scala用@clonable和@remote來(lái)標(biāo)記可被克隆的和遠(yuǎn)程的對(duì)象嫁乘。@varargs注解可以從Java調(diào)用Scala的帶有變長(zhǎng)參數(shù)的方法昆婿。

Scala類(lèi)庫(kù)中的有些注解可以控制編譯器的優(yōu)化,@tailrec 用于消除遞歸蜓斧,@switch 注解可以檢查scala的match語(yǔ)句是否真的被編譯成了跳轉(zhuǎn)表仓蛆,用@inline來(lái)建議編譯器做內(nèi)聯(lián),@editable給那些可以在生產(chǎn)代碼中移除的方法打上標(biāo)記挎春,對(duì)被省略的方法的調(diào)用看疙,編譯器會(huì)替換成Unit對(duì)象,@uncheckVariance會(huì)取消與型變相關(guān)的錯(cuò)誤提示直奋。

xml處理

Scala提供了對(duì)xml(當(dāng)然也就支持html了)的內(nèi)建支持能庆,可以用scala.xml.Elem的值表示一個(gè)XML元素。Node類(lèi)是所有xml節(jié)點(diǎn)類(lèi)型的父類(lèi)脚线,Elem類(lèi)描述xml元素搁胆。要處理某個(gè)元素的屬性鍵和值,可以用attributes屬性邮绿,然后用()來(lái)訪(fǎng)問(wèn)定鍵的值 渠旁,使用循環(huán)或asAttrMap方法遍歷所有屬性。

內(nèi)嵌的字符串會(huì)被轉(zhuǎn)成Atom[String]節(jié)點(diǎn)船逮,所以可在xml中包含scala代碼顾腊,被內(nèi)嵌的scala代碼還可以繼續(xù)包含XML片段,被引用的字符串當(dāng)中的花括號(hào)不會(huì)被解析和求值挖胃。

NodeSeq提供了類(lèi)似xpath中/,//的操作符杂靶,scala中用,\ 替代承耿,可以在模式匹配中使用xml的關(guān)鍵字。由于scala中xml節(jié)點(diǎn)和節(jié)點(diǎn)序列是不可變的伪煤,若要修改一個(gè)節(jié)點(diǎn),需創(chuàng)建拷貝凛辣,給出修改抱既,在拷貝未修改的部分。RuleTransformer類(lèi)的transform方法遍歷給定節(jié)點(diǎn)的所有后代扁誓,應(yīng)用所有規(guī)則防泵,最后返回經(jīng)過(guò)變換的樹(shù)。

Scala中的ContructingParser是個(gè)解析器蝗敢,用于加載xml捷泞,可以保留注釋?zhuān)珻DATA和空白,用doc.dtd可以訪(fǎng)問(wèn)到DTD寿谴。
保存XML時(shí)锁右,沒(méi)有內(nèi)容的元素不會(huì)被寫(xiě)成自結(jié)束的標(biāo)簽。Scala中每個(gè)元素都有一個(gè)scope屬性讶泰,類(lèi)型為NamespaceBinding,該類(lèi)的Uri屬性輸出命名空間的URI咏瑟。

高級(jí)函數(shù)和高級(jí)類(lèi)型

在scala中,函數(shù)是頭等公民痪署,可以用變量存儲(chǔ)函數(shù)码泞,可以使用匿名函數(shù),和帶參數(shù)的函數(shù)狼犯。如果需要一個(gè)序列的值余寥,一般從一個(gè)簡(jiǎn)單序列轉(zhuǎn)化得出。函數(shù)可以在變量不再作用域內(nèi)時(shí)被調(diào)用悯森,這樣的函數(shù)叫閉包宋舷。

柯里化是指將原來(lái)接受兩個(gè)參數(shù)變成接受一個(gè)參數(shù)的函數(shù)的過(guò)程。不需要用return語(yǔ)句來(lái)返回函數(shù)值呐馆,函數(shù)的返回值就是函數(shù)體的值肥缔。

scala中,用方括號(hào)來(lái)定義類(lèi)型參數(shù)汹来,從調(diào)用該方法的實(shí)際參數(shù)來(lái)推斷出類(lèi)型续膳。視圖界定 T<%V要求必須存在一個(gè)從T到V的隱式轉(zhuǎn)換,Manifest對(duì)象是構(gòu)造器的隱式參數(shù)收班,可用于上下文界定坟岔,類(lèi)型變化的方向和子類(lèi)型方向是相反的。

函數(shù)在參數(shù)上是逆變的摔桦,在返回值上的協(xié)變的社付,對(duì)象是不能泛型化的承疲。

在內(nèi)部,編譯器將所有嵌套的類(lèi)型表達(dá)式a.b.c.T都翻譯成類(lèi)型投影a.b.c.type#T鸥咖。對(duì)應(yīng)復(fù)雜類(lèi)型燕鸽,可用type關(guān)鍵字創(chuàng)建一個(gè)簡(jiǎn)單的別名,type同樣被用于那些在子類(lèi)中被具體化的抽象類(lèi)型。

結(jié)構(gòu)類(lèi)型指的是一組關(guān)于抽象方法啼辣,字段和類(lèi)型的規(guī)格說(shuō)明啊研,可用安全而方便的反射調(diào)用。

在scala中鸥拧,通過(guò)特質(zhì)和自身類(lèi)型達(dá)到一個(gè)簡(jiǎn)單的依賴(lài)注入效果党远。如果類(lèi)型是在類(lèi)實(shí)例化時(shí)給出,則使用泛型富弦,如果類(lèi)型是在子類(lèi)中給出沟娱,則使用抽象類(lèi)型。

List這樣的泛型類(lèi)型有時(shí)稱(chēng)為類(lèi)型構(gòu)造器腕柜。Container特質(zhì)是scala集合類(lèi)庫(kù)中使用的構(gòu)建器機(jī)制的的簡(jiǎn)化版济似。

Actor

actor提供了并發(fā)程序中與傳統(tǒng)的基于鎖的結(jié)構(gòu)不同的另一種選擇,通過(guò)盡可能避免鎖和共享狀態(tài)盏缤,actor更容易地設(shè)計(jì)出正確碱屁、沒(méi)有死鎖或爭(zhēng)用狀況的程序。Scala提供了actor的簡(jiǎn)單實(shí)現(xiàn)蛾找,akka(http://akka.io)提供了高級(jí)actor類(lèi)庫(kù)娩脾。

每個(gè)actor都要擴(kuò)展Actor類(lèi)并重寫(xiě)Act方法,actor是處理異步消息的對(duì)象打毛,消息可以是任何對(duì)象柿赊,通過(guò)!操作符發(fā)送消息幻枉,例如:

actorX 碰声!“happy new year”  

一個(gè)好的方式是使用樣例類(lèi)作為消息,這樣熬甫,actor可以使用模式匹配了胰挑。發(fā)送的消息存放在mailbox,receive方法從mailbox中取下一條消息并處理椿肩,如果在receive方法被調(diào)用時(shí)并沒(méi)消息瞻颂,則該調(diào)用會(huì)阻塞,直到有消息抵達(dá)郑象。actor可以安全地修改它自己的數(shù)據(jù)贡这。

向其他actor發(fā)送消息的方法:

  1. 使用全局的actor
  2. actor可以構(gòu)造成帶有指向一個(gè)或更多actor的引用
  3. actor可接收帶有指向另一個(gè)actor的引用的消息
  4. actor可以返回消息給發(fā)送方
    actor可以發(fā)送一個(gè)消息并等待回復(fù),用3ч弧盖矫?操作符即可丽惭,盡量避免同步消息。

actor的act方法在actor的start方法被調(diào)用時(shí)開(kāi)始執(zhí)行辈双。接下來(lái)進(jìn)入某個(gè)循環(huán)责掏,終止條件如下:

  1. act方法返回
  2. act方法由于異常被終止
  3. actor調(diào)用exit方法

通過(guò)link方法可以將不同的actor鏈接在一起。

actor的設(shè)計(jì)原則如下:

  1. 避免使用共享狀態(tài)
  2. 不要調(diào)用actor的方法
  3. 保持每個(gè)actor簡(jiǎn)單
  4. 上下文數(shù)據(jù)包含在消息中
  5. 最小化給發(fā)送方回復(fù)
  6. 最少阻塞調(diào)用
  7. 使用react
  8. 建立失敗區(qū)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末湃望,一起剝皮案震驚了整個(gè)濱河市拷橘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌喜爷,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件萄唇,死亡現(xiàn)場(chǎng)離奇詭異檩帐,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)另萤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)湃密,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人四敞,你說(shuō)我怎么就攤上這事泛源。” “怎么了忿危?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵达箍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我铺厨,道長(zhǎng)缎玫,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任解滓,我火速辦了婚禮赃磨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘洼裤。我一直安慰自己邻辉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布腮鞍。 她就那樣靜靜地躺著值骇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪移国。 梳的紋絲不亂的頭發(fā)上雷客,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音桥狡,去河邊找鬼搅裙。 笑死皱卓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的部逮。 我是一名探鬼主播娜汁,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼兄朋!你這毒婦竟也來(lái)了掐禁?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤颅和,失蹤者是張志新(化名)和其女友劉穎傅事,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體峡扩,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蹭越,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了教届。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片响鹃。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖案训,靈堂內(nèi)的尸體忽然破棺而出买置,到底是詐尸還是另有隱情,我是刑警寧澤强霎,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布忿项,位于F島的核電站,受9級(jí)特大地震影響城舞,放射性物質(zhì)發(fā)生泄漏倦卖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一椿争、第九天 我趴在偏房一處隱蔽的房頂上張望怕膛。 院中可真熱鬧,春花似錦秦踪、人聲如沸褐捻。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)柠逞。三九已至,卻和暖如春景馁,著一層夾襖步出監(jiān)牢的瞬間板壮,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工合住, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留绰精,地道東北人撒璧。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像笨使,于是被迫代替她去往敵國(guó)和親卿樱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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