自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

喜歡用Scala編程的四個(gè)理由:類型推斷潛力無(wú)窮

開發(fā) 后端
本文介紹了Scala令人喜愛的四大特點(diǎn):兼容性、簡(jiǎn)潔性、高層級(jí)以及其靜態(tài)類型的本質(zhì)。而Scala的類型推斷則成為了其最強(qiáng)大的武器之一。

Scala是為你準(zhǔn)備的嗎?你必須自己看明白并做決定。除了伸展性之外,我們發(fā)現(xiàn)喜歡用Scala編程實(shí)際上還有很多理由。最重要的四個(gè)將在本節(jié)討論的方面該是:兼容性,簡(jiǎn)短,高層級(jí)抽象和高級(jí)的靜態(tài)類別。其中,Scala的類型推斷可以走的很遠(yuǎn)。

51CTO編輯推薦:Scala編程語(yǔ)言專題

Scala的特點(diǎn):兼容

Scala不需要你從Java平臺(tái)后退兩步然后跳到Java語(yǔ)言前面去。它允許你在現(xiàn)存代碼中加點(diǎn)兒東西——在你已有的東西上建設(shè)——因?yàn)樗辉O(shè)計(jì)成無(wú)縫地與Java實(shí)施互操作。 Scala程序會(huì)被編譯為JVM的字節(jié)碼。它們的執(zhí)行期性能通常與Java程序一致。Scala代碼可以調(diào)用Java方法,訪問(wèn)Java字段,繼承自Java類和實(shí)現(xiàn)Java接口。這些都不需要特別的語(yǔ)法,顯式接口描述,或粘接代碼。實(shí)際上,幾乎所有Scala代碼都極度依賴于Java庫(kù),而經(jīng)常無(wú)須在程序員意識(shí)到這點(diǎn)。

交互式操作的另一個(gè)方面是Scala極度重用了Java類型。Scala的Int類型代表了Java的原始整數(shù)類型int,F(xiàn)loat代表了float,Boolean代表boolean,等等。Scala的數(shù)組被映射到Java數(shù)組。Scala同樣重用了許多標(biāo)準(zhǔn)Java庫(kù)類型。例如,Scala里的字串文本"abc"是java.lang.String,而拋出的異常必須是java.lang.Throwable的子類。

Scala不僅重用了Java的類型,還把它們“打扮”得更漂亮。例如,Scala的字串支持類似于toInt和toFloat的方法,可以把字串轉(zhuǎn)換成整數(shù)或者浮點(diǎn)數(shù)。因此你可以寫str.toInt替代Integer.parseInt(str)。如何在不打破互操作性的基礎(chǔ)上做到這點(diǎn)呢?Java的String類當(dāng)然不會(huì)有toInt方法。實(shí)際上,Scala有一個(gè)解決這種高級(jí)庫(kù)設(shè)計(jì)和互操作性不相和諧的通用方案。Scala可以讓你定義隱式轉(zhuǎn)換:implicit conversion,這常常用在類型失配,或者選用不存在的方法時(shí)。在上面的例子里,當(dāng)在字串中尋找toInt方法時(shí),Scala編譯器會(huì)發(fā)現(xiàn)String類里沒(méi)有這種方法,但它會(huì)發(fā)現(xiàn)一個(gè)把Java的String轉(zhuǎn)換為Scala的RichString類的一個(gè)實(shí)例的隱式轉(zhuǎn)換,里面定義了這么個(gè)方法。于是在執(zhí)行toInt操作之前,轉(zhuǎn)換被隱式應(yīng)用。

Scala代碼同樣可以由Java代碼調(diào)用。有時(shí)這種情況要更加微妙,因?yàn)镾cala是一種比Java更豐富的語(yǔ)言,有些Scala更先進(jìn)的特性在它們能映射到Java前需要先被編碼一下。第29章說(shuō)明了其中的細(xì)節(jié)。

Scala的特點(diǎn):簡(jiǎn)潔

Scala程序一般都很短。Scala程序員曾報(bào)告說(shuō)與Java比起來(lái)代碼行數(shù)可以減少到1/10。這有可能是個(gè)極限的例子。較保守的估計(jì)大概標(biāo)準(zhǔn)的Scala程序應(yīng)該有Java寫的同樣的程序一半行數(shù)左右。更少的行數(shù)不僅意味著更少的打字工作,同樣意味著更少的話在閱讀和理解程序上的努力及更少的出錯(cuò)可能。許多因素在減少代碼行上起了作用。

首先,Scala的語(yǔ)法避免了一些束縛Java程序的固定寫法。例如,Scala里的分號(hào)是可選的,且通常不寫。Scala語(yǔ)法里還有很多其他的地方省略了東西。比方說(shuō),比較一下你在Java和Scala里是如何寫類及構(gòu)造函數(shù)的。在Java里,帶有構(gòu)造函數(shù)的類經(jīng)常看上去是這個(gè)樣子:

// 在Java里

  1. class MyClass {  
  2.     private int index;  
  3.     private String name;  
  4.     public MyClass(int index, String name) {  
  5.         this.index = index;  
  6.         this.name = name;  
  7.     }  

在Scala里,你會(huì)寫成這樣:

  1. class MyClass(index: Int, name: String) 

根據(jù)這段代碼,Scala編譯器將制造有兩個(gè)私有成員變量的類,一個(gè)名為index的Int類型和一個(gè)叫做name的String類型,還有一個(gè)用這些變量作為參數(shù)獲得初始值的構(gòu)造函數(shù)。這個(gè)構(gòu)造函數(shù)還將用作為參數(shù)傳入的值初始化這兩個(gè)成員變量。一句話,你實(shí)際拿到了與羅嗦得多的Java版本同樣的功能。 Scala類寫起來(lái)更快,讀起來(lái)更容易,最重要的是,比Java類更不容易犯錯(cuò)。

有助于Scala的簡(jiǎn)潔易懂的另一個(gè)因素是它的類型推斷。重復(fù)的類型信息可以被忽略,因此程序變得更有條理和易讀。

但或許減少代碼最關(guān)鍵的是因?yàn)橐呀?jīng)存在于你的庫(kù)里而不需要寫的代碼。Scala給了你許多工具來(lái)定義強(qiáng)有力的庫(kù)讓你抓住并提煉出通用的行為。例如,庫(kù)類的不同方面可以被分成若干特質(zhì),而這些有可以被靈活地混合在一起。或者,庫(kù)方法可以用操作符參數(shù)化,從而讓你有效地定義那些你自己控制的構(gòu)造。這些構(gòu)造組合在一起,就能夠讓庫(kù)的定義既是高層級(jí)的又能靈活運(yùn)用。

Scala的特點(diǎn):高層級(jí)

程序員總是在和復(fù)雜性死磕。為了高產(chǎn)出的編程,你必須明白你工作的代碼。過(guò)度復(fù)雜的代碼成了很多軟件工程崩潰的原因。不幸的是,重要的軟件往往有復(fù)雜的需求。這種復(fù)雜性不可避免;必須(由不受控)轉(zhuǎn)為受控。

Scala可以通過(guò)讓你提升你設(shè)計(jì)和使用的接口的抽象級(jí)別來(lái)幫助你管理復(fù)雜性。例如,假設(shè)你有一個(gè)String變量name,你想弄清楚是否String包含一個(gè)大寫字符。

在Java里,你或許這么寫:

// 在Java里

  1. boolean nameHasUpperCase = false;  
  2. for (int i = 0; i < name.length(); ++i) {  
  3.  if (Character.isUpperCase(name.charAt(i))) {  
  4.   nameHasUpperCase = true;  
  5.   break;  
  6.  }  
  7. }  

在Scala里,你可以寫成:

  1. val nameHasUpperCase = name.exists(_.isUpperCase) 

Java代碼把字串看作循環(huán)中逐字符步進(jìn)的低層級(jí)實(shí)體。Scala代碼把同樣的字串當(dāng)作能用論斷:predicate查詢的字符高層級(jí)序列。明顯Scala代碼更短并且——對(duì)訓(xùn)練有素的眼睛來(lái)說(shuō)——比Java代碼更容易懂。因此Scala代碼在通盤復(fù)雜度預(yù)算上能極度地變輕。它也更少給你機(jī)會(huì)犯錯(cuò)。

論斷,_.isUpperCase,是一個(gè)Scala里面函數(shù)式文本的例子。 它描述了帶一個(gè)字符參量(用下劃線字符代表)的函數(shù),并測(cè)試其是否為大寫字母。

原則上,這種控制的抽象在Java中也是可能的。為此需要定義一個(gè)包含抽象功能的方法的接口。例如,如果你想支持對(duì)字串的查詢,就應(yīng)引入一個(gè)只有一個(gè)方法hasProperty的接口CharacterProperty:

// 在Java里

  1. interface CharacterProperty {  
  2.  boolean hasProperty(char ch);  
  3. }  

然后你可以在Java里用這個(gè)接口格式一個(gè)方法exists:它帶一個(gè)字串和一個(gè)CharacterProperty并返回真如果字串中有某個(gè)字符符合屬性。然后你可以這樣調(diào)用exists:

// 在Java里

  1. exists(name, new CharacterProperty {  
  2.  boolean hasProperty(char ch) {  
  3.   return Character.isUpperCase(ch);  
  4.  }  
  5. });  

然而,所有這些真的感覺很重。重到實(shí)際上多數(shù)Java程序員都不會(huì)惹這個(gè)麻煩。他們會(huì)寧愿寫個(gè)循環(huán)并漠視他們代碼里復(fù)雜性的累加。另一方面,Scala里的函數(shù)式文本真地很輕量,于是就頻繁被使用。隨著對(duì)Scala的逐步了解,你會(huì)發(fā)現(xiàn)越來(lái)越多定義和使用你自己的控制抽象的機(jī)會(huì)。你將發(fā)現(xiàn)這能幫助避免代碼重復(fù)并因此保持你的程序簡(jiǎn)短和清晰。

Scala的特點(diǎn):靜態(tài)類型

靜態(tài)類型系統(tǒng)認(rèn)定變量和表達(dá)式與它們持有和計(jì)算的值的種類有關(guān)。Scala堅(jiān)持作為一種具有非常先進(jìn)的靜態(tài)類型系統(tǒng)的語(yǔ)言。從Java那樣的內(nèi)嵌類型系統(tǒng)起步,能夠讓你使用泛型:generics參數(shù)化類型,用交集:intersection聯(lián)合類型和用抽象類型:abstract type隱藏類型的細(xì)節(jié)。 這些為建造和組織你自己的類型打下了堅(jiān)實(shí)的基礎(chǔ),從而能夠設(shè)計(jì)出即安全又能靈活使用的接口。

如果你喜歡動(dòng)態(tài)語(yǔ)言如Perl,Python,Ruby或Groovy,你或許發(fā)現(xiàn)Scala把它的靜態(tài)類型系統(tǒng)列為其優(yōu)點(diǎn)之一有些奇怪。畢竟,沒(méi)有靜態(tài)類型系統(tǒng)已被引為動(dòng)態(tài)語(yǔ)言的某些主要長(zhǎng)處。絕大多數(shù)普遍的針對(duì)靜態(tài)類型的論斷都認(rèn)為它們使得程序過(guò)度冗長(zhǎng),阻止程序員用他們希望的方式表達(dá)自己,并使軟件系統(tǒng)動(dòng)態(tài)改變的某些模式成為不可能。然而,這些論斷經(jīng)常針對(duì)的不是靜態(tài)類型的思想,而是指責(zé)特定的那些被意識(shí)到太冗長(zhǎng)或太不靈活的類型系統(tǒng)。例如,Alan Kay,Smalltalk語(yǔ)言的發(fā)明者,有一次評(píng)論:“我不是針對(duì)類型,而是不知道有哪個(gè)沒(méi)有完痛的類型系統(tǒng),所以我還是喜歡動(dòng)態(tài)類型。”

我們希望能在書里說(shuō)服你,Scala的類型系統(tǒng)是遠(yuǎn)談不上會(huì)變成“完痛”。實(shí)際上,它漂亮地說(shuō)明了兩個(gè)關(guān)于靜態(tài)類型通??紤]的事情(的解決方案):通過(guò)類型推斷避免了贅言和通過(guò)模式匹配及一些新的編寫和組織類型的辦法獲得了靈活性。把這些絆腳石搬掉后,靜態(tài)類型系統(tǒng)的經(jīng)典優(yōu)越性將更被賞識(shí)。其中最重要的包括程序抽象的可檢驗(yàn)屬性,安全的重構(gòu),以及更好的文檔。

可檢驗(yàn)屬性。靜態(tài)類型系統(tǒng)可以保證消除某些運(yùn)行時(shí)的錯(cuò)誤。例如,可以保證這樣的屬性:布爾型不會(huì)與整數(shù)型相加;私有變量不會(huì)從類的外部被訪問(wèn);函數(shù)帶了正確個(gè)數(shù)的參數(shù);只有字串可以被加到字串集之中。

不過(guò)當(dāng)前的靜態(tài)類型系統(tǒng)還不能查到其他類型的錯(cuò)誤。比方說(shuō),通常查不到無(wú)法終結(jié)的函數(shù),數(shù)組越界,或除零錯(cuò)誤。同樣也查不到你的程序不符合式樣書(假設(shè)有這么一份式樣書)。靜態(tài)類型系統(tǒng)因此被認(rèn)為不很有用而被忽視。輿論認(rèn)為既然這種類型系統(tǒng)只能發(fā)現(xiàn)簡(jiǎn)單錯(cuò)誤,而單元測(cè)試能提供更廣泛的覆蓋,又為何自尋煩惱呢?我們認(rèn)為這種論調(diào)不對(duì)頭。盡管靜態(tài)類型系統(tǒng)確實(shí)不能替代單元測(cè)試,但是卻能減少用來(lái)照顧那些確需測(cè)試的屬性的單元測(cè)試的數(shù)量。同樣,單元測(cè)試也不能替代靜態(tài)類型??偠灾鏓dsger Dijkstra所說(shuō),測(cè)試只能證明存在錯(cuò)誤,而非不存在。 因此,靜態(tài)類型能給的保證或許很簡(jiǎn)單,但它們是無(wú)論多少測(cè)試都不能給的真正的保證。

安全的重構(gòu)。靜態(tài)類型系統(tǒng)提供了讓你具有高度信心改動(dòng)代碼基礎(chǔ)的安全網(wǎng)。試想一個(gè)對(duì)方法加入額外的參數(shù)的重構(gòu)實(shí)例。在靜態(tài)類型語(yǔ)言中,你可以完成修改,重編譯你的系統(tǒng)并容易修改所有引起類型錯(cuò)誤的代碼行。一旦你完成了這些,你確信已經(jīng)發(fā)現(xiàn)了所有需要修改的地方。對(duì)其他的簡(jiǎn)單重構(gòu),如改變方法名或把方法從一個(gè)類移到另一個(gè),這種確信都有效。所有例子中靜態(tài)類型檢查會(huì)提供足夠的確認(rèn),表明新系統(tǒng)和舊系統(tǒng)可以一樣的工作。
文檔。靜態(tài)類型是被編譯器檢查過(guò)正確性的程序文檔。不像普通的注釋,類型標(biāo)注永遠(yuǎn)都不會(huì)過(guò)期(至少如果包含它的源文件近期剛剛通過(guò)編譯就不會(huì))。更進(jìn)一步說(shuō),編譯器和集成開發(fā)環(huán)境可以利用類型標(biāo)注提供更好的上下文幫助。舉例來(lái)說(shuō),集成開發(fā)環(huán)境可以通過(guò)判定選中表達(dá)式的靜態(tài)類型,找到類型的所有成員,并全部顯示出來(lái)。

雖然靜態(tài)類型對(duì)程序文檔來(lái)說(shuō)通常很有用,當(dāng)它們弄亂程序時(shí),也會(huì)顯得很討厭。標(biāo)準(zhǔn)意義上來(lái)說(shuō),有用的文檔是那些程序的讀者不可能很容易地從程序中自己想出來(lái)的。在如下的方法定義中:

  1. def f(x: String) = ...  

知道f的變量應(yīng)該是String是有用的。另一方面,以下例子中兩個(gè)標(biāo)注至少有一個(gè)是討厭的:

  1. val x: HashMap[Int, String] = new HashMap[Int, String]() 

很明顯,x是以Int為鍵,String為值的HashMap這句話說(shuō)一遍就夠了;沒(méi)必要同樣的句子重復(fù)兩遍。

Scala有非常精于此道的類型推斷系統(tǒng),能讓你省略幾乎所有的通常被認(rèn)為是討厭的類型信息。在上例中,以下兩個(gè)不太討厭的替代品也能一樣工作:

  1. val x = new HashMap[Int, String]()  
  2. val x: Map[Int, String] = new HashMap()  

Scala里的類型推斷可以走的很遠(yuǎn)。實(shí)際上,就算用戶代碼絲毫沒(méi)有顯式類型也不稀奇。因此,Scala編程經(jīng)??瓷先ビ悬c(diǎn)像是動(dòng)態(tài)類型腳本語(yǔ)言寫出來(lái)的程序。尤其顯著表現(xiàn)在作為粘接已寫完的庫(kù)控件的客戶應(yīng)用代碼上。而對(duì)庫(kù)控件來(lái)說(shuō)不是這么回事,因?yàn)樗鼈兂3S玫较喈?dāng)精妙的類型去使其適于靈活使用的模式。這很自然。綜上,構(gòu)成可重用控件接口的成員的類型符號(hào)應(yīng)該是顯式給出的,因?yàn)樗鼈儤?gòu)成了控件和它的使用者間契約的重要部分。

本文節(jié)選自Martin Odersky,Lex Spoon和Bill Venners所著,Regular翻譯的《Programming in Scala》的第一章。

【相關(guān)閱讀】

  1. Scala融合面向?qū)ο蠛秃瘮?shù)概念的方法
  2. Scala的語(yǔ)言特性——可伸展的語(yǔ)言
  3. 學(xué)習(xí)Scala中的Case類
  4. Groovy創(chuàng)始人:Java面臨終結(jié) Scala將取而代之
  5. Scala的類型系統(tǒng):取代復(fù)雜的通配符
責(zé)任編輯:楊鵬飛 來(lái)源: Artima
相關(guān)推薦

2020-06-04 08:15:53

Kubernetes容器PaaS

2024-09-29 09:22:00

2010-10-15 10:52:04

跳槽

2022-10-28 12:10:03

云計(jì)算企業(yè)

2016-04-21 16:02:16

SwiftAndroid編程

2019-07-18 11:58:27

安全分析師SOC網(wǎng)絡(luò)安全

2017-08-10 09:00:18

2023-11-03 00:28:44

ApacheFlink

2021-07-20 22:56:03

手機(jī)軟件iPhone

2011-12-22 11:12:49

Ubuntu操作系統(tǒng)

2009-07-14 09:06:08

Java對(duì)象類型轉(zhuǎn)換

2009-03-11 08:38:18

RIM黑莓移動(dòng)操作系統(tǒng)

2011-08-31 09:03:09

ScalaAndroid編程語(yǔ)言

2009-08-19 09:38:34

C++編程

2023-05-17 09:07:58

IT項(xiàng)目標(biāo)準(zhǔn)化

2010-08-10 09:34:14

FlexBlazeDS

2024-11-14 09:00:00

Python編程元編程

2016-04-26 10:19:39

周刊

2017-07-31 08:47:58

2022-09-23 14:05:53

邊緣計(jì)算工業(yè)部門
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)