国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Ruby高手點(diǎn)評(píng)Scala編程語(yǔ)言十大絕招

幾個(gè)月前,我開始使用 Scala。我用過的編程語(yǔ)言還有 Pascal、C、C++、Java、PHP、Ruby 和 Groovy,但是,與所有那些我用過的語(yǔ)言相比,我發(fā)覺 Scala 是一門與眾不同的語(yǔ)言。我是在看到 Twitter 上關(guān)于 Ruby 和 Scala 討論之后,才開始我的 Scala 編程之旅的?,F(xiàn)在,使用 Scala 編程已經(jīng)幾個(gè)月了,關(guān)于 Scala 我有兩點(diǎn)想法,雖然類似的想法已廣為人知,但我仍很想與你們分享:

◆Scala 的確很棒。

◆我的確認(rèn)為計(jì)算機(jī)學(xué)院應(yīng)該開一門 Scala 的語(yǔ)言課程。

在這篇文章中,我會(huì)講述為什么我會(huì)有這樣的想法,在此之前,有幾點(diǎn)我想要先聲明一下:

本文無(wú)意對(duì)編程語(yǔ)言進(jìn)行評(píng)比,我要講述的主體是為什么你應(yīng)該學(xué)習(xí) Scala。Scala中文之前曾發(fā)布過一篇 Java 程序員為何要學(xué)習(xí)Scala的文章,可能也會(huì)對(duì)你有所幫助。

目前 Scala 有兩個(gè)實(shí)現(xiàn)方式,一種是在 JVM(Java 虛擬機(jī))上運(yùn)行,另一種是在 CLR(Common Language Runtime 的縮寫,即公共語(yǔ)言運(yùn)行庫(kù))上運(yùn)行。不過,JVM 的實(shí)現(xiàn)方式更為成熟。如果你想要使用 .Net framework 框架,我認(rèn)為最好還是聽從 Lift framework 框架創(chuàng)始人大衛(wèi)·波拉克(David Pollack)的建議:使用 F#。但在這篇文章中,我將只關(guān)注 JVM 這種實(shí)現(xiàn)方式。

我是一個(gè) Ruby 程序員,并且我會(huì)繼續(xù)喜歡 Ruby,因?yàn)樗俏乙姷竭^的最棒的動(dòng)態(tài)語(yǔ)言。但我也喜歡 Scala,因?yàn)樵谄渌ぷ黝I(lǐng)域,它提供的某些功能非常強(qiáng)大。

現(xiàn)在,讓我們來仔細(xì)分析一下,是哪些原因讓我選擇 Scala 作為我的下一個(gè)編程語(yǔ)言:

強(qiáng)大的編程語(yǔ)言

Scala 是一門非常強(qiáng)大的語(yǔ)言,它允許用戶使用命令和函數(shù)范式進(jìn)行編寫代碼,因此,編程時(shí)你可以使用常用的命令式語(yǔ)句,就像我們使用 C、Java、PHP 以及很多其他語(yǔ)言一樣,而且,你也可以使用類似 Lisp 語(yǔ)言中函數(shù)式語(yǔ)句,還有,你可以混合使用這兩種風(fēng)格的語(yǔ)句,就像 Ruby 或 Groovy。

不過,當(dāng)我們談?wù)摰暮瘮?shù)范式時(shí),與 Ruby 和 Groovy 有一點(diǎn)不同的地方,那就是 Scala 幾乎支持函數(shù)語(yǔ)言中所有已知的功能,比如,模式匹配(Pattern matching)、延遲初始化(Lazy initialization)、偏函數(shù)(Partial Function)、不變性(Immutability),等等...即是說,認(rèn)識(shí)到這樣一個(gè)事實(shí)是非常重要的:Scala 的強(qiáng)大源自它對(duì)函數(shù)范式的支持,而后者令 Scala 成為一種高等級(jí)(high-level)的編程語(yǔ)言。對(duì)于高等級(jí)的編程語(yǔ)言,你只需關(guān)注 what(做什么)而不是如何做(how)。

下面,讓我們看一個(gè) Java 示例:

  1. int[] x = {1,2,3,4,5,6};   
  2. ArrayList res = new ArrayList();   
  3. for (int v : x) {   
  4. if (v % 2 == 1) res.add(new Integer(v));   

仔細(xì)看一下上面這段示例代碼,你會(huì)注意到,我想要做的“what”部分(過濾掉奇數(shù)值)僅出現(xiàn)在第四行中,而其余行則是“how”如何做的部分(結(jié)果變量的初始化以及一個(gè)循環(huán)操作)。如果我想要再寫一個(gè)過濾器,用于篩選偶數(shù)值,那就需要再寫五行代碼,而使用一門像 Scala 這樣的高等級(jí)語(yǔ)言,你只需編寫“what”那部分的代碼:

  1. val x = Array(1,2,3,4,5,6)   
  2. val res = x filter ( _ % 2 == 1 ) //過濾奇數(shù)值  
  3. val res2 = x filter ( _ % 2 == 0 ) //過濾偶數(shù)值 

我們可以看到,相對(duì)于上文中的 Java 代碼段,這段代碼更加簡(jiǎn)潔,而且具有更好的可讀性。

高效

Scala 是一種高效的編程語(yǔ)言,實(shí)際上,根據(jù)最新的 benchmark 性能測(cè)試,它幾乎和 Java 一樣快捷。在 JVM 上實(shí)現(xiàn)的 Scala 代碼,可以編譯為字節(jié)碼,在這一過程中,代碼通過優(yōu)化階段進(jìn)行編譯。尾遞歸優(yōu)化是一個(gè)很好的示例,它可幫助用戶專注于函數(shù)范式而無(wú)需以犧牲性能為代價(jià)。還有一個(gè)示例是,將 Scala 值類型對(duì)象轉(zhuǎn)換為 Java 基本類型時(shí)進(jìn)行的優(yōu)化。

可擴(kuò)展

Scala 語(yǔ)言本身的名字 Scala 來自 Scalable(可擴(kuò)展的)一詞,這意味著這種語(yǔ)言可以按照用戶的需求進(jìn)行擴(kuò)展。因此,從根本上來講,用戶可以添加新的類型和控制結(jié)構(gòu)。比如,我想要添加一個(gè)簡(jiǎn)單的“loop”控制結(jié)構(gòu):

  1. // 一個(gè)簡(jiǎn)單的構(gòu)建  
  2. def loop(range: Range)(op: Int=> Unit) {  
  3. range foreach (op)   
  4. }     
  5.  
  6. loop(1 to 5){println} // 1 2 3 4 5   
  7. loop(1 to 5){x => if (x % 2 == 0) println(x)} // 2 4  

還有幾個(gè)更為復(fù)雜的例子,Actor lib,它是作為擴(kuò)展被添加到 Scala 這一語(yǔ)言中的,我們將在下文中對(duì)它展開討論。

不過,Scala 之所以是可擴(kuò)展的,在于互相關(guān)聯(lián)的兩點(diǎn):它是真正的面向?qū)ο蟮恼Z(yǔ)言和真正的函數(shù)式語(yǔ)言。

面向?qū)ο?/strong>

Scala 中每個(gè)事物都是對(duì)象(對(duì)象的方法除外),因此,沒有必要對(duì)基本(primitive)類型或引用類型進(jìn)行區(qū)分,這就是所謂的:統(tǒng)一對(duì)象模型(Uniform Object Model)。但是,正如我之前在優(yōu)化流程中所提到的,值類型對(duì)象被轉(zhuǎn)換為 Java 基本類型,因此不必?fù)?dān)心性能的問題。其內(nèi)部還包含為類方法分組的單件對(duì)象(Singleton object)。

◆所有操作都是方法調(diào)用,+ - * ! / 都是方法,因此,沒有必要進(jìn)行操作符重載。

◆非常精細(xì)的訪問控制,用戶可以控制對(duì)某些包的某些方法的訪問。

◆Scala 具有  trait,與 Ruby 中的 mixin 類似,就像 Java 中的 interfaces,但實(shí)現(xiàn)了某些它們的方法,因此,用戶在箱體(box)之外擁有富封裝器(wrapper)和富交互接口(interface)。

函數(shù)式語(yǔ)言

函數(shù)式語(yǔ)言具有很多特點(diǎn),不過在擴(kuò)展性這一語(yǔ)境中,我們所關(guān)心的是兩個(gè)事實(shí):

◆函數(shù)是第一等級(jí)(first-class)的值

這表示用戶可以將函數(shù)作為值傳遞,也可以作為值返回。這樣可以獲得簡(jiǎn)潔而具有可讀性的代碼,正如上文中作為示例的過濾代碼段。

◆純函數(shù)(pure function)

Scala 支持沒有副作用的純函數(shù),這意味著:如果你的輸入相同,那么輸出結(jié)果也總是相同。這樣能夠讓代碼更為安全,對(duì)代碼測(cè)試也更為方便。

但是,Scala 是通過什么方式來支持純函數(shù)的呢?通過不變性(immutability):偏向固定的引用(與 java 中的 final 或其他語(yǔ)言中的 constant 類似)以及具有不變的數(shù)據(jù)結(jié)構(gòu),一旦創(chuàng)建便不可修改。

不變性是擁有純函數(shù)的安全保證,但并不是唯一的方式。沒有不變性,你仍然可以編寫安全的代碼。這就是為什么 Scala 不是強(qiáng)制推行不變性而只是鼓勵(lì)使用它。最終,你會(huì)發(fā)現(xiàn) Scala 中許多數(shù)據(jù)結(jié)構(gòu)具有了兩種實(shí)現(xiàn)方式,一種是可變的,另一種是不可變的,不可變的數(shù)據(jù)結(jié)構(gòu)是缺省導(dǎo)入的。

每當(dāng)提到不變性時(shí),有人就會(huì)開始擔(dān)心性能的問題,對(duì)于某些情況,這種擔(dān)憂并非毫無(wú)來由,但對(duì)于 Scala,最終結(jié)果卻與這一擔(dān)憂相反。不可變的數(shù)據(jù)結(jié)構(gòu)相對(duì)于可變的數(shù)據(jù)結(jié)構(gòu),更有助于獲得較高的效率。其原因之一在于強(qiáng)大的垃圾收集器(garbage collector),與 JVM 中的垃圾收集器類似。

更佳的并行模型

當(dāng)涉及到線程這一問題時(shí),Scala 支持傳統(tǒng)的 shared data 模型。但是,使用這種模型較長(zhǎng)一段時(shí)間之后,許多人發(fā)現(xiàn)使用這種模型編寫代碼,非常難以實(shí)現(xiàn)以及進(jìn)行測(cè)試。你總是需要考慮死鎖問題和競(jìng)爭(zhēng)條件。因此,Scala 提供了另一個(gè)稱為 Actor 的并行模型,其中,actor 通過它的收件箱來發(fā)送和接收非同步信息,而不是共享數(shù)據(jù)。這種方式被稱為:shared nothing 模型。一旦你不再顧慮共享數(shù)據(jù)的問題,也就不必再為代碼同步和死鎖問題而頭痛。

被發(fā)送信息的不變性本質(zhì)以及 actor 中串行處理,這兩者使得對(duì)于并行的支持更為簡(jiǎn)便。

有關(guān) Scala 并行的問題,請(qǐng)參閱這篇文章,對(duì)于這個(gè)概念你會(huì)有更好的理解。

在講述下一個(gè)要點(diǎn)之前,我需要提到這樣一個(gè)事實(shí),一些人將 Actor 的使用視為編程語(yǔ)言的一種進(jìn)化。正如,Java 的出現(xiàn),將程序員們從指針和內(nèi)存管理的泥淖中拯救出來一樣,Scala 的到來,讓程序員們不必再為代碼同步以及共享數(shù)據(jù)模型整天苦思冥想。

 

靜態(tài)類型

當(dāng)我想要講述這一要點(diǎn)的時(shí)候,才發(fā)現(xiàn),對(duì)于靜態(tài)類型語(yǔ)言的正反兩面,我試圖給予同樣的關(guān)注。事實(shí)上,關(guān)于這一話題的爭(zhēng)論總是沒完沒了,但我要作出兩點(diǎn)總結(jié),而這兩點(diǎn)是大多數(shù)人討論的熱點(diǎn):

◆使用靜態(tài)類型語(yǔ)言編寫的代碼更加健壯(robust)

TDD 的存在,讓許多關(guān)于動(dòng)態(tài)類型語(yǔ)言和健壯代碼的討論失去了意義,雖然這是正確的,當(dāng)我們?nèi)匀徊荒芎鲆曔@樣一個(gè)事實(shí):對(duì)于動(dòng)態(tài)類型語(yǔ)言,你需要編寫更多的測(cè)試代碼來檢查類型,而在靜態(tài)類型語(yǔ)言中,你可以將這些問題交給編譯器處理。此外,還有一些人認(rèn)為,使用靜態(tài)類型語(yǔ)言,你的代碼將具有更好的自我記錄。

◆使用靜態(tài)類型語(yǔ)言編寫的代碼過于嚴(yán)格和冗長(zhǎng)

像我這樣的動(dòng)態(tài)類型語(yǔ)言的粉絲,認(rèn)為通過鴨子類型(duck typing)可以寫出更具動(dòng)態(tài)性的代碼結(jié)構(gòu)。但同時(shí)他們還會(huì)抱怨,靜態(tài)類型語(yǔ)言導(dǎo)致代碼冗長(zhǎng)。

關(guān)于靜態(tài)類型與動(dòng)態(tài)類型的爭(zhēng)論,在Scala中文之前發(fā)布的這篇文章中可以看到更多信息。

作為靜態(tài)類型語(yǔ)言,Scala 具有第一條中提到的優(yōu)點(diǎn),但是,第二點(diǎn)呢?

Scala 具有一個(gè)靈活的類型系統(tǒng),并且可能是這一類型中最好的。很多情況下,如果你沒有指定類型,這一系統(tǒng)將能夠?qū)︻愋瓦M(jìn)行推斷。

例如,你可以這樣編寫代碼:

  1. val list: List[String] = List("one""two""three")   
  2. //list: List[String] = List(one, two, three)     
  3. val s: String = "Hello World!"   
  4. //s: java.lang.String = hello world! 

但你也可以這樣編寫代碼:

  1. val list = List("one""two""three")   
  2. //list: List[String] = List(one, two, three)     
  3. val s = "Hello World!"   
  4. //s: java.lang.String = hello world! 

非常好,無(wú)論如何,它解決了代碼冗長(zhǎng)的問題。但像鴨子類型(duck typing)那樣的問題,會(huì)怎樣呢?

答案還是:Scala 的類型系統(tǒng)具有的某些靈活性,可以讓你編寫如下的代碼:

  1. def eat[T <: Animal](a: T) // whatever 

其中,我們將類型 T 定義為 Animal 的子類型。還可以更加靈活:

  1. def eat[T <: {def eat(): Unit}](a: T) // whatever 

其中,我們將類型 T 定義為一個(gè)具有非法  eat 的類型。

事實(shí)上,Scala 的類型系統(tǒng)非常豐富,你可以在這里找到更多信息。

模式匹配

我必須坦白,在猶豫良久之后,我才決定寫一寫 Scala 的這一特點(diǎn)。事實(shí)上,我本來沒有打算討論 Scala 的函數(shù)功能,但看到一篇有關(guān)對(duì)象分支(switch)應(yīng)用的文章后,我想,還是有必要聊聊這個(gè)特點(diǎn)。以下內(nèi)容基本上都來自這篇博客文章:

模式匹配究竟是用來做什么的?它讓你可以將一個(gè)值對(duì)多種情況(case)進(jìn)行匹配,有點(diǎn)類似 Java 中的分支(switch)語(yǔ)句。但它不是僅僅匹配數(shù)字(這是分支語(yǔ)句的作用),而是用戶能夠?qū)Ρ举|(zhì)上為對(duì)象創(chuàng)建形式(creation form)的事物進(jìn)行匹配。

以下示例也來自上文提到的博客:

  1. x match {   
  2. case Address(Name(first, last), street, city, state, zip) => println(last + ", " + zip)   
  3. case _ => println("not an address"// 缺省情況   

對(duì)于第一種情況,模式 Name(first, last) 嵌套在模式 Address(…) 中。 其中的 last 值,被傳遞到 Name 構(gòu)造函數(shù),然后進(jìn)行提取,因此在箭頭右側(cè)的表達(dá)式中是可用的。

那么,

模式匹配的意義

為什么你需要模式匹配?我們都會(huì)有復(fù)雜的數(shù)據(jù)。如果我們堅(jiān)持嚴(yán)格的面向?qū)ο缶幊?,那么我們就不愿去關(guān)注數(shù)據(jù)樹的內(nèi)部情況。相反,我們想要調(diào)用方法,讓方法來做這些事情。如果我們有能力完成這件事,就不會(huì)非常需要模式匹配,因?yàn)榉椒M足了我們的要求。但是,很多時(shí)候?qū)ο鬀]有我們所需的方法,并且我們不能(或不愿)為對(duì)象添加新的方法。

因此,模式匹配被認(rèn)為是一種獲得擴(kuò)張性的有效方法,并且,它還為該問題提供了一種不錯(cuò)的解決方案,訪問者設(shè)計(jì)模式所導(dǎo)致的冗長(zhǎng)除外。

不管怎樣,強(qiáng)烈推薦你看看上面所提到的文章中”擴(kuò)展性的兩個(gè)方向“(Two directions of extensibility)那個(gè)小節(jié)。

簡(jiǎn)單的 DSL(特定領(lǐng)域語(yǔ)言)

編寫 DSL,Scala 是一個(gè)很好的選擇。事實(shí)上,Scala 適用于內(nèi)部和外部 DSL。在這篇文章中,你可以找到一些使用 Ruby 和 Scala 編寫內(nèi)部 DSL 的特點(diǎn)比較。下面這篇文章也很棒,是關(guān)于使用 Scala 編寫內(nèi)部 DSL 的:Boolean Algebra Internal DSL in Scala (aka fun with Unicode names )。

此外,對(duì)于外部 DSL,Scala 也應(yīng)該是首選語(yǔ)言,背后的原因是解析器組合子庫(kù)(parser combinator lib),它讓為新語(yǔ)言編寫編譯器成為一件很酷的事。

與 Java 代碼之間的互操作性

在 JVM 上的實(shí)現(xiàn) Scala 的程序可以無(wú)縫地與 Java 平臺(tái)整合,很多 Scala 類型實(shí)際上都編譯為 Java 類型,因此,用戶可以放心地使用 Java 類型。而且,你也可以混合地使用 JVM 語(yǔ)言來編程,如:JRuby、Groovy、Clojure 等。這里有一篇不錯(cuò)的文章,提供了這種示例。

學(xué)習(xí)型語(yǔ)言

我有兩個(gè)習(xí)慣,在 Scala 的學(xué)習(xí)過程中,我堅(jiān)持了這兩個(gè)習(xí)慣:

◆遇到新的技術(shù)術(shù)語(yǔ),訪問維基百科,理解更多信息;比如 Function literal(文本函數(shù))、Referentially transparent(引用透明度)、Partial function(偏函數(shù))、Currying(科里華),還有很多其他術(shù)語(yǔ)。

◆參考我對(duì)其他語(yǔ)言的理解,檢查這些術(shù)語(yǔ)的涵義是否實(shí)現(xiàn)。

通過一些好的練習(xí),如編寫沒有副作用的純函數(shù),將精力集中在代碼中的“what”部分,而將“how”的部分交給語(yǔ)言處理;這兩個(gè)習(xí)慣讓我獲得更多知識(shí),也提高了代碼的質(zhì)量。

團(tuán)隊(duì)

Scala 由馬丁·奧德斯基(Martin Odersky)設(shè)計(jì),他是瑞士聯(lián)邦理工學(xué)院洛桑分校(EPFL)編程方法實(shí)驗(yàn)室小組的管理者。奧德斯基曾受雇于 Sun 公司編寫 Java 1.1 編譯器,他還是 Java 1.1 到 Java 1.4 的 Javac 主要開發(fā)者。此外,他還是 Java Generics 的提出者。有人曾通過電子郵件與奧德斯基就 Scala 的語(yǔ)言特性進(jìn)行了交流,并得到了回復(fù)信件如下

Scala 現(xiàn)在由奧德斯基和他在瑞士聯(lián)邦理工學(xué)院洛桑分校的團(tuán)隊(duì)維護(hù)。不過,還有其他一些具有才華的開發(fā)者參與,通過多年的工作,他們共同打造出了 Scala 這一編程語(yǔ)言。

來源

Scala 受到了多種語(yǔ)言的啟發(fā)

◆大多數(shù)的句法來自 Java 和 C#。

◆其他一些元素也來自 Java,比如:基本類型(basic type)、類庫(kù),以及其運(yùn)行模型。

◆它所用的統(tǒng)一對(duì)象模型是由 Smalltalk 最先使用的。

◆通用嵌套(universal nesting)的理念也出現(xiàn)在 Algol、Simula 中,而且最近還出現(xiàn)在 Beta 和 gbeta 中。

◆函數(shù)式編碼的方法在精神上也與 ML 語(yǔ)言家族類似,該語(yǔ)言家族中包含 SML、OCaml,以及最主要的成員 F#。

◆Scala 標(biāo)準(zhǔn)庫(kù)中的許多較高階的函數(shù),也出現(xiàn)在 ML 和 Haskell 中。

◆Scala 的隱式參數(shù)也是受到 Haskell 類型類的啟發(fā)。Scala 基于 actor 的并行庫(kù)主要是受到 Erlang 的啟發(fā)。

◆將插入(infix)操作符視為函數(shù),以及允許文本函數(shù)(或 block 區(qū)塊)作為參數(shù),以使庫(kù)能夠定義控制結(jié)構(gòu),這些特定的理念可以回溯至 Iswim 和Smalltalk。

專家觀點(diǎn)

實(shí)際上,像詹姆士·斯特拉坎(James Strachan:編程語(yǔ)言 Groovy 的創(chuàng)始人)的這樣的言語(yǔ)讓人感到有點(diǎn)驚喜:

說實(shí)話,如果有人在 2003 年給我一本由馬丁·奧德斯基(Martin Odersky)、萊克斯·斯彭(Lex Spoon)和比爾·文納斯(Bill Venners)合著的《Programming in Scala》,我很可能不會(huì)再去創(chuàng)建 Groovy。

在結(jié)束之前,我做一下總結(jié):

我喜歡 Scala,因?yàn)樗歉咝У摹W(xué)習(xí)型的語(yǔ)言,具有較好的并行模型,以及非常適用于編寫 DSL。

原文:Scala is my next choice

作者:khelll    譯者:司馬牽牛

(責(zé)任編輯:Scala中文)
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服