官术网_书友最值得收藏!

第2章 字符串

作為程序員,我們經常和字符串打交道,如名字、地址、電話號碼等。Scala提供的字符串操作非常棒,因為除了擁有Java字符串的全部功能以外,還有一些新的擴展。本章將會在一些小節中介紹其字符串格式化和正則表達式相關的功能,而其他的小節則會展示Scala字符串的一些獨有的功能。

Scala與Java語法一個最大的區別是字符串的聲明方式。所有的Scala變量都是以val或var的形式聲明的,因此一個字符串變量通常是這樣創建的:

這個表達式與下面的Java代碼等價:

在Scala中,一般來說總是將變量聲明為val,除非有充分的理由使用var。(純函數式編程要求則更嚴格,禁止使用var。)

也可以顯式地聲明成字符串類型:

這么做只會讓代碼變得冗長,所以并不推薦。因為Scala的類型推斷非常強大,所以第一個例子中使用的隱式語法就是首選方式。在實際情況下,我其實只有在調用一個方法并且不確定其返回類型時,才會在創建變量時明確聲明其類型,例如:

Scala字符串功能

Scala字符串的功能有:

·能使用==來比較字符串是否相等。

·多行字符串。

·字符串插值操作,可以寫出類似println(s"Name: $name")的代碼。

·數十種額外的函數方法可以將字符串當作字符序列來處理。

本章將展示所有這些功能。

字符串是字符序列

上面提到的比較新穎的一個要點是,Scala的字符串可以被當作字符序列來看待,也就是當作Seq[Char]。因此,給出以下字符串:

下面是一些常用的“序列”方法,可以在該字符串上進行調用:

這些方法都是Seq的標準方法,將在第11章中深入介紹。

鏈式方法調用

Seq上所有的方法都是“函數式”的,這意味著它們不會改變現有的序列,而是在調用時返回一個新的序列,但foreach方法是一個例外,它返回Unit。由于這種函數式特點,可以在字符串上使用鏈式調用:

如果你之前沒有見過這種寫法,這里我先簡單介紹一下這個例子的工作原理:drop是集合的一個方法,它從集合的開頭丟棄指定數量的元素,保留剩余的元素。當這里調用drop(2)時,它從字符串(scala)中丟掉前兩個字符(sc),并返回剩余的元素:

然后,take(2)方法保留了字符串"ala"中的前2個字符,并丟棄了其他字符:

最后,調用capitalize得到最終結果:

如果不熟悉這樣的鏈式調用,它也被稱為流式編程風格。請參閱8.8節以了解更多的信息。在函數式編程中這種代碼非常常見,每個函數都是純函數并返回一個值。這種風格同樣在RxJava和RxScala等Rx技術中很流行,同時也被大量用于Apache Spark中。

這些方法從哪來

熟悉Java的人都知道Java的String類并沒有capitalize方法,所以Scala上有這個方法可能會讓人驚訝。Scala字符串在Java字符串的基礎上擴充了幾十個額外的方法,而這些方法可以通過Eclipse或者IntelliJ IDEA等IDE的“代碼輔助”功能看到。

當你通過這種方式看到這些可用的方法并且得知Scala沒有字符串類時,可能會覺得很驚訝。如果沒有String類,字符串是如何擁有這些方法的?

其工作原理是,Scala通過隱式轉換和擴展方法“繼承”了Java的String類,從而完成了向其添加方法的功能。隱式轉換是Scala 2中向封閉類添加方法的方式,而擴展方法則是Scala 3中使用的方式。關于如何創建擴展方法的細節,請參閱8.9節。

雖然這可能會隨著時間的推移而改變,但在Scala 3.0中,Scala字符串的許多額外方法定義在StringOps類中,這些方法會隨著scala.Predef自動導入代碼中,在Scala 2.13的Predef對象(它也被Scala 3所使用)中可以找到這個隱式轉換以及相關文檔:

augmentString將一個字符串轉換成StringOps類型。這樣做會將StringOps中的方法添加到所有的Scala字符串實例中,其中包括drop、take和filter這些能把字符串當作字符序列處理的方法。

閱讀Predef源代碼

我強烈建議Scala的初學者閱讀Scala 2.13的scala.Predef對象(https://oreil.ly/kkdJM)的源碼,可以在Scaladoc頁面上找到源代碼鏈接,它提供了許多與Scala編程特性相關的例子。可以看到它是如何引入其他像StringOps和WrappedString這樣的類型的。

主站蜘蛛池模板: 乐昌市| 长宁县| 饶平县| 南溪县| 富民县| 调兵山市| 将乐县| 当阳市| 昭苏县| 隆子县| 江门市| 双城市| 贡山| 察雅县| 崇州市| 苍山县| 梅河口市| 南陵县| 莱阳市| 七台河市| 隆林| 凤山县| 栖霞市| 澎湖县| 汉中市| 眉山市| 同江市| 大渡口区| 海宁市| 伊宁市| 高邮市| 澄江县| 无极县| 双鸭山市| 绵竹市| 和林格尔县| 满洲里市| 图木舒克市| 西平县| 洛南县| 芜湖市|