Scala學習(一)--Scala基礎學習


Scala基礎學習

摘要

在篇主要內容:如何把Scala當做工業級的便攜計算器使用,如何用Scala處理數字以及其他算術操作。在這個過程中,我們將介紹一系列重要的Scala概念和慣用法。同時你還將學到作為初學者如何瀏覽Scaladoc文檔

1. 使用Scala解釋器

2. 用var和val定義變量

3. 數值類型

4. 使用操作符和函數

5. 瀏覽Scaladoc

Scala解釋器

啟動Scala解釋器的步驟如下:

安裝Scala

確保scala/bin目錄位於系統PATH中

在你的操作系統中打開命令行窗口,鍵入scala並按Enter鍵

現在鍵人命令,然后按Enter鍵。每一次,解釋器都會顯示出結果。例如,當你鍵人"8*5+2"(如下面加粗的文字),將得到42:

答案被命名為res0,你可以在后續操作中使用這個名稱:

正如你所看到的,解釋器同時還會顯示結果的類型,拿本例來說就是Int、Double和java.lang.String

還可以調用方法,根據啟動解釋器的方式的不同,你可能可以使用Tab鍵補全而不用完整地手工鍵人方法名。你可以試着鍵人res2.to,然后按Tab鍵,如果解釋器給出了如下選項:

說明Tab鍵補全功能是好的。接下來鍵入U並再次按Tab鍵,你應該就能定位到單條補全如下:

同樣地,可以試試按T和J方向鍵。在大多數實現當中,你將看到之前提交過的命令,並且可以進行編輯。用方向鍵和Del鍵將上一條命令修改為:

正如你所看到的,Scala解釋器讀到一個表達式,對它進行求值,將它打印出來,接着再繼續讀下一個表達式。這個過程被稱做讀取求值打印循環,即REPL。從技術上講,scala程序並不是一個解釋器。實際發生的是,你輸入的內容被快速地編譯成字節碼,然后這段字節碼交由Java虛擬機執行。正因如此,大多數Scala程序員更傾向於將它稱做"REPL"。

聲明值和變量

聲明值

除了直接使用res0、res1等這些名稱之外,你也可以用val定義自己的名稱:

以val定義的值實際上是一個常量,你無法改變它的內容:

聲明變量

如果要聲明其值可變的變量,可以用var定義其值可變的變量

需要注意的是,不需要給出或者變量的類型這個信息可以從你用來初始化它的表達式推斷出來。但還需注意一點,聲明值或變量但不做初始化會報錯。不過,在必要的時候,你也可以指定類型。例如:

由上圖運行的結果可知,在Scala中,變量或函數的類型總是寫在變量或函數名稱的后面。這使得我們更容易閱讀那些復雜類型的聲明。同時還需注意的是,在變量聲明或賦值語句之后,我們並沒有使用分號。在Scala中,僅當同一行代碼中存在多條語句時才需要用分號隔開

常用類型

基本數據類型:

到目前為止你已經看到過Scala數據類型中的一些,比如Int和Double,和Java樣Scala也有7種數值類型:Byte、Char、Short、Int、Long、Float和Double,以及1個Boolean類型。跟Java不同的是,這些類型是類。Scala並不刻意區分基本類型引用類型。你可以對數字執行方法,例如:

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中,我們不需要包裝類型。在基本類型包裝類型之間的轉換是Scala編譯器的工作。舉例來說,如果你創建一個Int的數組,最終在虛擬機中得到的是一個int[]數組。

基本數據類型轉換:

正如你在前面看到的那樣,Scala用底層的java.lang.String類來表示字符串。不過,它通過StringOps類給字符串追加了上百種操作。舉例來說,intersect方法輸出兩個字符串共通的一組字符:

scala> "Hello".intersect("World")

res8: String = lo

在這個表達式中java.lang.String對象"Hello"被隱式地轉換成了一個StringOps對象,接着StringOps類的intersect方法被應用。因此,在使用Scala文檔的時候,記得要看一下StringOps類。同樣地,Scala還提供了RichlntRichDoubleRichChar等。它們分別提供了它們可憐的堂兄弟們IntDoubleChar等,所不具備的便捷方法。我們前面用到的to方法事實上就是Richlnt類中的方法。在表達式:1.to (10)中,Int值1首先被轉換成Richlnt然后再應用to方法。

最后,還有BiglntBigDecimal類,用於任意大小(但有窮)的數字。這些類背后分別對應的是java.math.Biglnteger和java.math.BigDecimal

注意:在Scala中,我們用方法,而不是強制類型轉換,來做數值類型之間的轉換。舉例來說,99.44.tolnt得到99,99.toChar得到'c'。當然和Java一樣,toString任意的對象轉換成字符串。要將包含了數字的字符串轉換成數值,使用tolnt或toDouble。例如,"99.44".toDouble得到99.44。

算術和操作符重載

Scala的算術操作符和你在Java或C++中預期的效果是一樣的:

val answer=8*5+2

算術操作符:+ -*/%等操作符完成的是它們通常的工作,位操作符:&|^ >><<也一樣。只有一點特別的,這些操作符實際上是方法。例如:

a+b

是如下方法調用的簡寫:

a.+(b)

這里的+方法名。通常來說,你可以用:

a方法b

作為以下代碼的簡寫:

a.方法(b)

這里的方法是一個帶有兩個參數的方法(一個隱式的和一個顯式的)。例如

1.to (10)

可以寫成:

1 to10

調用函數方法

除了方法之外,Scala還提供函數。相比Java,在Scala中使用數學函數更為簡單,你不需要從某個類調用它的靜態方法

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

這些數學函數是在scala.math包中定義的。你可以用如下語句進行引入:

import scala.math._//在Scala中,_字符是"通配符",類似Java中的*字符

Scala沒有靜態方法,不過它有個類似的特性,叫做單例對象singleton object。通常,一個類對應有一個伴生對象companion object,其方法就跟Java中的靜態方法一樣

apply方法

在Scala中,我們通常都會使用類似函數調用的語法。舉例來說,如果S是一個字符串,那么S(i)就是該字符串的第i個字符。在C++中,你會寫:S[i];而在Java中,你會這樣寫:S.charAt(i)。在REPL中運行如下代碼:

scala> "Hello"(4)

res19: Char = o

scala> "Hello"(0)

res20: Char = H

scala>

你可以把這種用法當做是()操作符重載形式,它背后的實現原理是一個名為apply的方法。舉例來說,在StringOps類的文檔中,你會發現這樣一個方法:

def apply(n: Int): Char

也就是說,"Hello"(4)是如下語句的簡寫:

"Hello".apply(4)

如果你去看Biglnt伴生對象的文檔,就會看到讓你將字符串數字轉換為Biglnt對象的apply方法。舉例來說,如下調用

Biglnt ("1234567890")

是如下語句的簡寫:

Biglnt.apply("1234567890")

這個語句產出一個新的Biglnt對象,不需要使用new。例如:

Biglnt("1234567890") *Biglnt("112358111321")

像這樣使用伴生對象的apply方法是Scala中構建對象的常用手法。例如,Array(l,4,9,16)返回一個數組,用的就是Array伴生對象的apply方法

Scaladoc

Java程序員們使用Javadoc來瀏覽Java AP,Scala也有它自己的版本,叫做Scaladoc。相比Javadoc,瀏覽Scaladoc更具挑戰性。Scala類通常比Java類擁有多得多的便捷方

法。有些方法使用了你還沒學到的特性。而且,有些特性展示出來的是它們的實現細節而並不是使用指南。我們可以在www.scala-lang.org/api在線瀏覽Scaladoc,不過也可以從www.scala-lang.org/downloads#api下載一個副本安裝到本地。

和Javadoc按照字母順序列出類清單不同,Scaladoc的類清單按照包排序。如果你知道類名但不知道包名,可以用左上角的過濾器,參照下圖:

點擊×號可以清空過濾器。注意每個類名旁邊的O和C,它們分別鏈接到對應的(C)或伴生對象(O)。由於信息量大,Scaladoc可能讀起來會比較累人。請記住以下這些小竅門:

■ 如果你想使用數值類型,記得看看Richlnt、RichDouble等。同理,如果想使用字符串,記得看看SpringOps

■ 那些數學函數位於scala.math包中,而不是位於某個類中

■ 有時你會看到名稱比較奇怪的函數。比如,Biglnt有一個方法叫做unary_-。這就是你定義前置的負操作符-x的方式

標記為implicit的方法對應的是自動(隱式)轉換。比如,Biglnt對象擁有在需要時自動被調用的由int和long轉換為Biglnt的方法

■ 方法可以以函數作為參數。例如,StringOps的count方法需要傳人一個接受單個Char並返回true或false的函數,用於指定哪些字符應當被清點:

def count(p: (Char)=>Boolean) : Int

調用類似方法時,你通常可以一種非常緊湊的表示法給出函數定義。例如,s.count(_.isUpper)的作用是清點所有大寫字母的數量 

■ 你時不時地會遇到類似RangeSeq[Char]這樣的類。它們的含義和你的直覺告訴你的一樣:一個是數字區間,一個是字符序列

如果,您認為閱讀這篇博客讓您有些收獲,不妨點擊一下右下角的【推薦】。
如果,您希望更容易地發現我的新博客,不妨點擊一下左下角的【關注我】。
如果,您對我的博客所講述的內容有興趣,請繼續關注我的后續博客,我是【Sunddenly】。

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM