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

Scala程序及其Application特質(zhì)

開(kāi)發(fā) 后端
本文節(jié)選自Martin Odersky,Lex Spoon和Bill Venners所著,Regular翻譯的《Programming in Scala》的第四章。Scala是一種針對(duì) JVM 將函數(shù)和面向?qū)ο蠹夹g(shù)組合在一起的編程語(yǔ)言。

要執(zhí)行Scala程序,你一定要提供一個(gè)有main方法(僅帶一個(gè)參數(shù),Array[String],且結(jié)果類型為Unit)的孤立單例對(duì)象名。任何擁有合適簽名的main方法的單例對(duì)象都可以用來(lái)作為程序的入口點(diǎn)。代碼4.3展示了一個(gè)例子:

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

  1. // 文件Summer.scala  
  2. import ChecksumAccumulator.calculate  
  3. object Summer {  
  4.  def main(args: Array[String]) {  
  5.   for (arg < - args)  
  6.    println(arg + ": " + calculate(arg))  
  7.  }  
  8. }  

代碼 4.3 程序Summer

代碼4.3單例對(duì)象的名字是Summer。它的main方法具有合適的簽名,所以你可以把它用作程序。文件中的第一個(gè)語(yǔ)句是引用定義在前例中ChecksumAccumulator對(duì)象中的calculate方法。這個(gè)引用語(yǔ)句允許你在文件之后的部分里使用方法的簡(jiǎn)化名。如果你是Java程序員,你可以認(rèn)為這種引用類似于Java 5引入的精通引用特性。然而Scala里的一個(gè)不同是,你可以從任何對(duì)象引用成員,而不只是單例對(duì)象。main方法體簡(jiǎn)單地打印輸出每個(gè)參數(shù)和參數(shù)的校驗(yàn)和,用冒號(hào)分隔。

注意

Scala隱式引用了包java.lang和scala的成員,和名為Predef的單例對(duì)象的成員,到每個(gè)Scala源文件中。Predef,被放置在包scala中,包含了許多有用的方法。例如,當(dāng)在Scala源文件中寫(xiě)pringln的時(shí)候,你實(shí)際調(diào)用了Predef的println。(Predef.pringln運(yùn)轉(zhuǎn)并調(diào)用Console.println,做實(shí)際的工作。)當(dāng)你寫(xiě)assert,你是在調(diào)用Predef.assert。

要執(zhí)行Summer應(yīng)用程序,把代碼4.3的代碼放在文件Summer.scala中。因?yàn)镾ummer使用了ChecksumAccumulator,把ChecksumAccumulator的代碼,包括代碼4.1的類和代碼4.2里它的伴生對(duì)象,放在文件ChecksumAccumulator.scala中。

Scala和Java之間有一點(diǎn)不同,Java需要你在跟著類命名的文件里放上一個(gè)公共類——如文件SpeedRacer.java里要放上類SpeedRacer——Scala里,你可以任意命名.scala文件,而不用考慮里面放了什么Scala類或代碼。然而通常情況下如果不是腳本,推薦的風(fēng)格是像在Java里那樣按照所包含的類名來(lái)命名文件,這樣程序員就可以通過(guò)查看文件名的方式更容易地找到類。這就是我們?cè)诒纠形募﨏hecksumAccumulator.scala和Summer.scala上使用的方式。

無(wú)論ChecksumAccumulator.scala還是Summer.scala都不是腳本,因?yàn)樗麄兪且远x結(jié)束的。反過(guò)來(lái)說(shuō),腳本必然以一個(gè)結(jié)果表達(dá)式結(jié)束。因此如果你嘗試以腳本方式執(zhí)行Summer.scala,Scala解釋器將會(huì)報(bào)錯(cuò)說(shuō)Summer.scala不是以結(jié)果表達(dá)式結(jié)束的(當(dāng)然前提是你沒(méi)有在Summer對(duì)象定義之后加上任何你自己的表達(dá)式)。正確的做法是,你需要用Scala編譯器真正地編譯這些文件,然后執(zhí)行輸出的類文件。其中一種方式是使用scalac,Scala的基本編譯器。輸入:

  1. $ scalac ChecksumAccumulator.scala Summer.scala 

這將編譯你的源文件,不過(guò)在編譯完成之前或許會(huì)有一個(gè)可感知的停頓。原因是每次編譯器啟動(dòng)時(shí),都要花一些時(shí)間掃描jar文件內(nèi)容,并在即使你提交的是新的源文件也在查看之前完成其他初始化工作。因此,Scala的發(fā)布包里還包括了一個(gè)叫做fsc(快速Scala編譯器)的Scala編譯器后臺(tái)服務(wù):daemon。你可以這樣使用:

  1. $ fsc ChecksumAccumulator.scala Summer.scala 

第一次執(zhí)行fsc時(shí),會(huì)創(chuàng)建一個(gè)綁定在你計(jì)算機(jī)端口上的本地服務(wù)器后臺(tái)進(jìn)程。然后它就會(huì)把文件列表通過(guò)端口發(fā)送給后臺(tái)進(jìn)程去編譯,后臺(tái)進(jìn)程完成編譯。下一次你執(zhí)行fsc時(shí),后臺(tái)進(jìn)程就已經(jīng)在運(yùn)行了,于是fsc將只是把文件列表發(fā)給后臺(tái)進(jìn)程,它會(huì)立刻開(kāi)始編譯文件。使用fsc,你只需要在第一次等待Java運(yùn)行時(shí)環(huán)境的啟動(dòng)。如果想停止fsc后臺(tái)進(jìn)程,可以執(zhí)行fsc -shutdown來(lái)關(guān)閉。

不論執(zhí)行scalac還是fsc命令,都將創(chuàng)建Java類文件,然后你可以用scala命令,就像之前的例子里調(diào)用解釋器那樣運(yùn)行它。不過(guò),不是像前面每個(gè)例子里那樣把包含了Scala代碼的帶有.scala擴(kuò)展名的文件交給它解釋執(zhí)行,scala程序用來(lái)“解釋”Scala源文件的真正機(jī)制是,它把Scala源碼編譯成字節(jié)碼,然后立刻通過(guò)類裝載器裝載它們,并執(zhí)行它們。在這里你要給它包含了正確簽名的main方法的孤立對(duì)象名。因此,你可以這樣運(yùn)行Summer應(yīng)用程序:

  1. $ scala Summer of love 

你會(huì)看到兩個(gè)命令行參數(shù)的校驗(yàn)和被打印出來(lái):

  1. of: -213 
  2. love: -182 

Application特質(zhì)

Scala提供了一個(gè)特質(zhì),scala.Application,可以節(jié)省你一些手指的輸入工作。盡管我們還沒(méi)有完全提供給你去搞明白它如何工作的所有需要知道的東西,不過(guò)我們還是認(rèn)為你可能想要知道它。代碼4.4展示了一個(gè)例子:

  1. import ChecksumAccumulator.calculate  
  2. object FallWinterSpringSummer extends Application {  
  3.  for (season < - List("fall""winter""spring"))  
  4.   println(season +": "+ calculate(season))  
  5. }  

代碼 4.4 使用Application特質(zhì)

使用這個(gè)特質(zhì)的方法是,首先在你的單例對(duì)象名后面寫(xiě)上“extends Application” 。然后代之以main方法,你可以把想要放在main方法里的代碼直接放在單例對(duì)象的大括號(hào)之間。就這么簡(jiǎn)單。之后可以像對(duì)其它程序那樣編譯和運(yùn)行。

這種方式之所以能奏效是因?yàn)樘刭|(zhì)Application聲明了帶有合適的簽名的main方法,并由你的單例對(duì)象繼承,使它可以像個(gè)Scala程序那樣用。大括號(hào)之間的代碼被收集進(jìn)了單例對(duì)象的主構(gòu)造器:primary constructor,并在類被初始化時(shí)被執(zhí)行。如果你不明白所有這些指的是什么也不用著急。之后的章節(jié)會(huì)解釋這些,目前可以暫時(shí)不求甚解。

繼承自Application比寫(xiě)個(gè)顯式的main方法要短,不過(guò)它也有些缺點(diǎn)。首先,如果想訪問(wèn)命令行參數(shù)的話就不能用它,因?yàn)閍rgs數(shù)組不可訪問(wèn)。比如,因?yàn)镾ummer程序使用了命令行參數(shù),所以它必須帶有顯式的main方法,如代碼4.3所示。第二,因?yàn)槟承㎎VM線程模型里的局限,如果你的程序是多線程的就需要顯式的main方法。最后,某些JVM的實(shí)現(xiàn)沒(méi)有優(yōu)化被Application特質(zhì)執(zhí)行的對(duì)象的初始化代碼。因此只有當(dāng)你的程序相對(duì)簡(jiǎn)單和單線程情況下你才可以繼承Application特質(zhì)。

【相關(guān)閱讀】

  1. Scala程序中的分號(hào)推斷和Singleton對(duì)象
  2. 學(xué)習(xí)Scala類的定義,字段和方法
  3. 學(xué)習(xí)Scala腳本:從文件里讀取行記錄
  4. 學(xué)習(xí)識(shí)別Scala的函數(shù)式風(fēng)格
  5. Scala編程實(shí)例:使用Set和Map

責(zé)任編輯:book05 來(lái)源: Artima
相關(guān)推薦

2009-07-22 07:44:00

Scala尾遞歸

2016-12-19 17:35:58

程序員特質(zhì)

2009-07-22 07:53:00

Scala擴(kuò)展類

2009-06-16 15:20:48

ApplicationJSP程序

2014-01-07 10:12:15

Spark

2009-08-14 17:08:00

Android應(yīng)用程序

2009-07-22 08:52:05

Scala動(dòng)態(tài)綁定

2018-10-24 10:24:41

JavaScala開(kāi)發(fā)者

2009-07-20 18:03:26

Scala程序Singleton對(duì)象

2010-01-07 10:05:51

IT顧問(wèn)特質(zhì)

2023-02-28 11:18:57

CUPID代碼

2009-09-22 09:42:24

Scala的核心

2012-11-09 13:44:48

ScalaJVMJava

2009-05-26 09:00:59

ScalaJava面向?qū)ο?/a>

2009-07-08 12:43:59

Scala ServlScala語(yǔ)言

2009-08-21 16:17:25

ScalaTwitter API

2010-09-14 15:34:41

Scala

2009-09-28 11:01:39

從Java走進(jìn)Scal

2015-02-05 10:11:44

HTML5Application

2009-11-16 17:04:46

Inside Scal
點(diǎn)贊
收藏

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