Scala学习(一)--Scala基础学习
| Scala基礎(chǔ)學(xué)習(xí) |
摘要:
在篇主要內(nèi)容:如何把Scala當(dāng)做工業(yè)級(jí)的便攜計(jì)算器使用,如何用Scala處理數(shù)字以及其他算術(shù)操作。在這個(gè)過程中,我們將介紹一系列重要的Scala概念和慣用法。同時(shí)你還將學(xué)到作為初學(xué)者如何瀏覽Scaladoc文檔
1. 使用Scala解釋器
2. 用var和val定義變量
3. 數(shù)值類型
4. 使用操作符和函數(shù)
5. 瀏覽Scaladoc
| Scala解釋器 |
啟動(dòng)Scala解釋器的步驟如下:
安裝Scala
確保scala/bin目錄位于系統(tǒng)PATH中
在你的操作系統(tǒng)中打開命令行窗口,鍵入scala并按Enter鍵
現(xiàn)在鍵人命令,然后按Enter鍵。每一次,解釋器都會(huì)顯示出結(jié)果。例如,當(dāng)你鍵人"8*5+2"(如下面加粗的文字),將得到42:
答案被命名為res0,你可以在后續(xù)操作中使用這個(gè)名稱:
正如你所看到的,解釋器同時(shí)還會(huì)顯示結(jié)果的類型,拿本例來說就是Int、Double和java.lang.String
還可以調(diào)用方法,根據(jù)啟動(dòng)解釋器的方式的不同,你可能可以使用Tab鍵補(bǔ)全而不用完整地手工鍵人方法名。你可以試著鍵人res2.to,然后按Tab鍵,如果解釋器給出了如下選項(xiàng):
說明Tab鍵補(bǔ)全功能是好的。接下來鍵入U(xiǎn)并再次按Tab鍵,你應(yīng)該就能定位到單條補(bǔ)全如下:
同樣地,可以試試按T和J方向鍵。在大多數(shù)實(shí)現(xiàn)當(dāng)中,你將看到之前提交過的命令,并且可以進(jìn)行編輯。用方向鍵和Del鍵將上一條命令修改為:
正如你所看到的,Scala解釋器讀到一個(gè)表達(dá)式,對(duì)它進(jìn)行求值,將它打印出來,接著再繼續(xù)讀下一個(gè)表達(dá)式。這個(gè)過程被稱做讀取一求值一打印一循環(huán),即REPL。從技術(shù)上講,scala程序并不是一個(gè)解釋器。實(shí)際發(fā)生的是,你輸入的內(nèi)容被快速地編譯成字節(jié)碼,然后這段字節(jié)碼交由Java虛擬機(jī)執(zhí)行。正因如此,大多數(shù)Scala程序員更傾向于將它稱做"REPL"。
| 聲明值和變量 |
聲明值:
除了直接使用res0、res1等這些名稱之外,你也可以用val定義自己的名稱:
以val定義的值實(shí)際上是一個(gè)常量,你無法改變它的內(nèi)容:
聲明變量:
如果要聲明其值可變的變量,可以用var定義其值可變的變量:
需要注意的是,不需要給出值或者變量的類型,這個(gè)信息可以從你用來初始化它的表達(dá)式推斷出來。但還需注意一點(diǎn),聲明值或變量但不做初始化會(huì)報(bào)錯(cuò)。不過,在必要的時(shí)候,你也可以指定類型。例如:
由上圖運(yùn)行的結(jié)果可知,在Scala中,變量或函數(shù)的類型總是寫在變量或函數(shù)名稱的后面。這使得我們更容易閱讀那些復(fù)雜類型的聲明。同時(shí)還需注意的是,在變量聲明或賦值語句之后,我們并沒有使用分號(hào)。在Scala中,僅當(dāng)同一行代碼中存在多條語句時(shí)才需要用分號(hào)隔開。
| 常用類型 |
基本數(shù)據(jù)類型:
到目前為止你已經(jīng)看到過Scala數(shù)據(jù)類型中的一些,比如Int和Double,和Java樣Scala也有7種數(shù)值類型:Byte、Char、Short、Int、Long、Float和Double,以及1個(gè)Boolean類型。跟Java不同的是,這些類型是類。Scala并不刻意區(qū)分基本類型和引用類型。你可以對(duì)數(shù)字執(zhí)行方法,例如:
scala> 1.toString
res6: String = 1
或者,更有意思的是,你可以:
scala> 1.to(10)
res7: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8,9, 10)
在Scala中,我們不需要包裝類型。在基本類型和包裝類型之間的轉(zhuǎn)換是Scala編譯器的工作。舉例來說,如果你創(chuàng)建一個(gè)Int的數(shù)組,最終在虛擬機(jī)中得到的是一個(gè)int[]數(shù)組。
基本數(shù)據(jù)類型轉(zhuǎn)換:
正如你在前面看到的那樣,Scala用底層的java.lang.String類來表示字符串。不過,它通過StringOps類給字符串追加了上百種操作。舉例來說,intersect方法輸出兩個(gè)字符串共通的一組字符:
scala> "Hello".intersect("World")
res8: String = lo
在這個(gè)表達(dá)式中java.lang.String對(duì)象"Hello"被隱式地轉(zhuǎn)換成了一個(gè)StringOps對(duì)象,接著StringOps類的intersect方法被應(yīng)用。因此,在使用Scala文檔的時(shí)候,記得要看一下StringOps類。同樣地,Scala還提供了Richlnt、RichDouble、RichChar等。它們分別提供了它們可憐的堂兄弟們Int、Double、Char等,所不具備的便捷方法。我們前面用到的to方法事實(shí)上就是Richlnt類中的方法。在表達(dá)式:1.to (10)中,Int值1首先被轉(zhuǎn)換成Richlnt然后再應(yīng)用to方法。
最后,還有Biglnt和BigDecimal類,用于任意大小(但有窮)的數(shù)字。這些類背后分別對(duì)應(yīng)的是java.math.Biglnteger和java.math.BigDecimal
注意:在Scala中,我們用方法,而不是強(qiáng)制類型轉(zhuǎn)換,來做數(shù)值類型之間的轉(zhuǎn)換。舉例來說,99.44.tolnt得到99,99.toChar得到'c'。當(dāng)然和Java一樣,toString將任意的對(duì)象轉(zhuǎn)換成字符串。要將包含了數(shù)字的字符串轉(zhuǎn)換成數(shù)值,使用tolnt或toDouble。例如,"99.44".toDouble得到99.44。
| 算術(shù)和操作符重載 |
Scala的算術(shù)操作符和你在Java或C++中預(yù)期的效果是一樣的:
val answer=8*5+2
算術(shù)操作符:+ -*/%等操作符完成的是它們通常的工作,位操作符:&|^ >><<也一樣。只有一點(diǎn)特別的,這些操作符實(shí)際上是方法。例如:
a+b
是如下方法調(diào)用的簡寫:
a.+(b)
這里的+是方法名。通常來說,你可以用:
a方法b
作為以下代碼的簡寫:
a.方法(b)
這里的方法是一個(gè)帶有兩個(gè)參數(shù)的方法(一個(gè)隱式的和一個(gè)顯式的)。例如
1.to (10)
可以寫成:
1 to10
| 調(diào)用函數(shù)方法 |
除了方法之外,Scala還提供函數(shù)。相比Java,在Scala中使用數(shù)學(xué)函數(shù)更為簡單,你不需要從某個(gè)類調(diào)用它的靜態(tài)方法
scala> import scala.math._
import scala.math._
scala> sqrt(2)
res15: Double = 1.4142135623730951
scala> pow(2,4)
res16: Double = 16.0
scala> min(3,Pi)
res18: Double = 3.0
這些數(shù)學(xué)函數(shù)是在scala.math包中定義的。你可以用如下語句進(jìn)行引入:
import scala.math._//在Scala中,_字符是"通配符",類似Java中的*字符
Scala沒有靜態(tài)方法,不過它有個(gè)類似的特性,叫做單例對(duì)象singleton object。通常,一個(gè)類對(duì)應(yīng)有一個(gè)伴生對(duì)象companion object,其方法就跟Java中的靜態(tài)方法一樣
| apply方法 |
在Scala中,我們通常都會(huì)使用類似函數(shù)調(diào)用的語法。舉例來說,如果S是一個(gè)字符串,那么S(i)就是該字符串的第i個(gè)字符。在C++中,你會(huì)寫:S[i];而在Java中,你會(huì)這樣寫:S.charAt(i)。在REPL中運(yùn)行如下代碼:
scala> "Hello"(4)
res19: Char = o
scala> "Hello"(0)
res20: Char = H
scala>
你可以把這種用法當(dāng)做是()操作符的重載形式,它背后的實(shí)現(xiàn)原理是一個(gè)名為apply的方法。舉例來說,在StringOps類的文檔中,你會(huì)發(fā)現(xiàn)這樣一個(gè)方法:
def apply(n: Int): Char
也就是說,"Hello"(4)是如下語句的簡寫:
"Hello".apply(4)
如果你去看Biglnt伴生對(duì)象的文檔,就會(huì)看到讓你將字符串或數(shù)字轉(zhuǎn)換為Biglnt對(duì)象的apply方法。舉例來說,如下調(diào)用
Biglnt ("1234567890")
是如下語句的簡寫:
Biglnt.apply("1234567890")
這個(gè)語句產(chǎn)出一個(gè)新的Biglnt對(duì)象,不需要使用new。例如:
Biglnt("1234567890") *Biglnt("112358111321")
像這樣使用伴生對(duì)象的apply方法是Scala中構(gòu)建對(duì)象的常用手法。例如,Array(l,4,9,16)返回一個(gè)數(shù)組,用的就是Array伴生對(duì)象的apply方法
| Scaladoc |
Java程序員們使用Javadoc來瀏覽Java AP,Scala也有它自己的版本,叫做Scaladoc。相比Javadoc,瀏覽Scaladoc更具挑戰(zhàn)性。Scala類通常比Java類擁有多得多的便捷方
法。有些方法使用了你還沒學(xué)到的特性。而且,有些特性展示出來的是它們的實(shí)現(xiàn)細(xì)節(jié)而并不是使用指南。我們可以在www.scala-lang.org/api在線瀏覽Scaladoc,不過也可以從www.scala-lang.org/downloads#api下載一個(gè)副本安裝到本地。
和Javadoc按照字母順序列出類清單不同,Scaladoc的類清單按照包排序。如果你知道類名但不知道包名,可以用左上角的過濾器,參照下圖:
點(diǎn)擊×號(hào)可以清空過濾器。注意每個(gè)類名旁邊的O和C,它們分別鏈接到對(duì)應(yīng)的類(C)或伴生對(duì)象(O)。由于信息量大,Scaladoc可能讀起來會(huì)比較累人。請(qǐng)記住以下這些小竅門:
■ 如果你想使用數(shù)值類型,記得看看Richlnt、RichDouble等。同理,如果想使用字符串,記得看看SpringOps
■ 那些數(shù)學(xué)函數(shù)位于scala.math包中,而不是位于某個(gè)類中
■ 有時(shí)你會(huì)看到名稱比較奇怪的函數(shù)。比如,Biglnt有一個(gè)方法叫做unary_-。這就是你定義前置的負(fù)操作符-x的方式
■ 標(biāo)記為implicit的方法對(duì)應(yīng)的是自動(dòng)(隱式)轉(zhuǎn)換。比如,Biglnt對(duì)象擁有在需要時(shí)自動(dòng)被調(diào)用的由int和long轉(zhuǎn)換為Biglnt的方法
■ 方法可以以函數(shù)作為參數(shù)。例如,StringOps的count方法需要傳人一個(gè)接受單個(gè)Char并返回true或false的函數(shù),用于指定哪些字符應(yīng)當(dāng)被清點(diǎn):
def count(p: (Char)=>Boolean) : Int
調(diào)用類似方法時(shí),你通常可以一種非常緊湊的表示法給出函數(shù)定義。例如,s.count(_.isUpper)的作用是清點(diǎn)所有大寫字母的數(shù)量?
■ 你時(shí)不時(shí)地會(huì)遇到類似Range或Seq[Char]這樣的類。它們的含義和你的直覺告訴你的一樣:一個(gè)是數(shù)字區(qū)間,一個(gè)是字符序列
如果,您認(rèn)為閱讀這篇博客讓您有些收獲,不妨點(diǎn)擊一下右下角的【推薦】。
如果,您希望更容易地發(fā)現(xiàn)我的新博客,不妨點(diǎn)擊一下左下角的【關(guān)注我】。
如果,您對(duì)我的博客所講述的內(nèi)容有興趣,請(qǐng)繼續(xù)關(guān)注我的后續(xù)博客,我是【Sunddenly】。
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
總結(jié)
以上是生活随笔為你收集整理的Scala学习(一)--Scala基础学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IDEA API文档的导出方式
- 下一篇: 隐藏实施过程