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

第6步 用foreach方法和for-do遍歷

你可能還沒有意識到,當你在前一步寫下while循環時,實際上是在以指令式imperative)的風格編程。指令式編程風格也是類似Java、C++、Python這樣的語言通常的風格,需要依次給出執行指令,通過循環來遍歷,而且經常變更被不同函數共享的狀態。Scala允許以指令式的風格編程,不過隨著對Scala的了解日益加深,你應該經常會發現自己傾向于使用更加函數式functional)的風格。事實上,本書的一個主要目標就是幫助你像適應指令式編程風格那樣,也能習慣和適應函數式編程風格。

函數式編程語言的主要特征之一就是函數是一等的語法單元,Scala非常符合這個描述。舉例來說,打印每一個命令行參數的另一種(精簡得多的)方式是:

在這段代碼中,對args執行foreach方法,傳入一個函數。在本例中,傳入的是一個函數字面量function literal),這個(匿名)函數接收一個名稱為arg的參數。函數體為println(arg)。如果你把上述內容錄入一個新的名稱為pa.scala的文件中并執行:

則應該會看到:

在前面的示例中,Scala編譯器推斷出arg的類型是String,因為String是調用foreach那個數組的元素類型。如果你傾向于更明確的表達方式,也可以指出類型名。不過當你這樣做的時候,需要將參數的部分包在圓括號里(這是函數字面量的常規語法):

執行這個腳本的效果與執行前一個腳本的效果一致。

如果你更喜歡精簡的表達方式而不是事無巨細的表達方式,則可以利用Scala對函數字面量的一個特殊簡寫規則。如果函數字面量只是一個接收單個參數的語句,則可以不必給出參數名和參數本身。[11]因此,下面這段代碼依然是可以工作的:

我們來總結一下,Scala的函數字面量語法是:用圓括號括起來的一組帶名稱的參數、一個右箭頭和函數體,如圖2.2所示。

圖2.2 Scala的函數字面量語法

至此,你也許會好奇,我們熟知的指令式編程語言(如Java或Python)中那些for循環到哪里去了。為了鼓勵和引導大家使用更函數式的編程風格,Scala只支持指令式for語句的函數式親戚(這個親戚叫作for表達式)。在讀到7.3節之前,你可能無法領略for表達式的全部功能和超強的表達力,在此我們將帶你快速地體驗一下。在一個新的名稱為forargs.scala的文件中錄入以下內容:

在“for”和“do”之間是“arg <- args”。[12]位于<-符號右邊的,是我們熟知的args數組。而在<-符號的左邊的是“arg”,這是一個val變量的名稱,注意它不是var。(因為它總是val,所以只需要寫“arg”而不用寫成“val arg”。)雖然arg看上去像是var,因為每一次迭代都會拿到新的值,但是它確實是一個val——arg不能在for表達式的循環體內被重新賦值。實際情況是,對于args數組中的每一個元素,一個“新的”名稱為argval會被創建出來,并初始化成元素的值,這時for表達式的循環體才被執行。

如果用下面的命令執行forargs.scala腳本:

將會看到:

Scala的for表達式能做到的遠不止這些,不過這個示例代碼已經足以讓你用起來了。我們將在7.3節及《Scala高級編程》中更詳細地介紹for表達式。

主站蜘蛛池模板: 汉阴县| 方城县| 凭祥市| 墨竹工卡县| 革吉县| 汶川县| 黄浦区| 博湖县| 湖州市| 柘城县| 历史| 蒙城县| 加查县| 开江县| 正定县| 门源| 德惠市| 丰县| 中江县| 高台县| 南宫市| 盐山县| 新昌县| 博白县| 镇坪县| 房产| 大同市| 冀州市| 泸水县| 元阳县| 阳朔县| 来宾市| 建德市| 林甸县| 鸡东县| 平凉市| 衡山县| 芦溪县| 苍溪县| 盐城市| 工布江达县|