日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
有趣的Scala語(yǔ)言:簡(jiǎn)潔的Scala語(yǔ)法

一、Scala開(kāi)發(fā)環(huán)境

搭建Scala 開(kāi)發(fā)環(huán)境,一是在IntelliJ IDEA 上安裝Scala 插件和安裝Scala SDK,二是通過(guò)Scala RELP(Read-Eval-Print Loop)交互式環(huán)境,該交互式環(huán)境適合代碼簡(jiǎn)單調(diào)試,不太適合進(jìn)行應(yīng)用開(kāi)發(fā)。

二、變量和函數(shù)

定義變量時(shí)沒(méi)有指定變量類(lèi)型。這是否意味著 Scala 是和 Python 或者 Ruby 一樣的動(dòng)態(tài)類(lèi)型語(yǔ)言呢?恰恰相反,Scala 是嚴(yán)格意義上的靜態(tài)類(lèi)型語(yǔ)言,由于其采用了類(lèi)型推斷(Type Inference)技術(shù),程序員不需要在寫(xiě)程序時(shí)顯式指定類(lèi)型,編譯器會(huì)根據(jù)上下文推斷出類(lèi)型信息。比如變量 x被賦值為 0,0 是一個(gè)整型,所以 x的類(lèi)型被推斷出為整型。當(dāng)然,Scala 語(yǔ)言也允許顯示指定類(lèi)型,如變量 x1,y1的定義。一般情況下,我們應(yīng)盡量使用 Scala 提供的類(lèi)型推斷系統(tǒng)使代碼看上去更加簡(jiǎn)潔。

另一個(gè)發(fā)現(xiàn)是程序語(yǔ)句結(jié)尾沒(méi)有分號(hào),這也是 Scala 中約定俗成的編程習(xí)慣。大多數(shù)情況下分號(hào)都是可省的,如果你需要將兩條語(yǔ)句寫(xiě)在同一行,則需要用分號(hào)分開(kāi)它們。

函數(shù)的定義也非常簡(jiǎn)單,使用關(guān)鍵字 def,后跟函數(shù)名和參數(shù)列表,如果不是遞歸函數(shù)可以選擇省略函數(shù)返回類(lèi)型。Scala 還支持定義匿名函數(shù),匿名函數(shù)由參數(shù)列表,箭頭連接符和函數(shù)體組成。函數(shù)在 Scala 中屬于一級(jí)對(duì)象,它可以作為參數(shù)傳遞給其他函數(shù),可以作為另一個(gè)函數(shù)的返回值,或者賦給一個(gè)變量。在下面的示例代碼中,定義的匿名函數(shù)被賦給變量 cube。匿名函數(shù)使用起來(lái)非常方便,比如 List對(duì)象中的一些方法需要傳入一個(gè)簡(jiǎn)單的函數(shù)作為參數(shù),我們當(dāng)然可以定義一個(gè)函數(shù),然后再傳給 List對(duì)象中的方法,但使用匿名函數(shù),程序看上去更加簡(jiǎn)潔。

 
 
 
  1. // 定義函數(shù) 
  2. def square(x: Int): Int = x * x 
  3. // 如果不是遞歸函數(shù),函數(shù)返回類(lèi)型可省略 
  4. def sum_of_square(x: Int, y: Int) = square(x) + square(y) 
  5. sum_of_square(2, 3)
 
 
 
  1. // 定義匿名函數(shù) 
  2. val cube = (x: Int) => x * x *x 
  3. cube(3) 
  4. // 使用匿名函數(shù),返回列表中的正數(shù) 
  5. List(-2, -1, 0, 1, 2, 3).filter(x => x > 0)

讓我們?cè)賮?lái)和 Java 中對(duì)應(yīng)的函數(shù)定義語(yǔ)法比較一下。首先,函數(shù)體沒(méi)有像 Java 那樣放在 {}里。Scala 中的一條語(yǔ)句其實(shí)是一個(gè)表達(dá)式,函數(shù)的執(zhí)行過(guò)程就是對(duì)函數(shù)體內(nèi)的表達(dá)式的求值過(guò)程,最后一條表達(dá)式的值就是函數(shù)的返回值。如果函數(shù)體只包含一條表達(dá)式,則可以省略 {}。其次,沒(méi)有顯示的 return語(yǔ)句,最后一條表達(dá)式的值會(huì)自動(dòng)返回給函數(shù)的調(diào)用者。

和 Java 不同,在 Scala 中,函數(shù)內(nèi)部還可以定義其他函數(shù)。比如上面的程序中,如果用戶(hù)只對(duì) sum_of_square 函數(shù)感興趣,則我們可以將 square 函數(shù)定義為內(nèi)部函數(shù),實(shí)現(xiàn)細(xì)節(jié)的隱藏。

定義內(nèi)部函數(shù):

三、流程控制語(yǔ)句

復(fù)雜一點(diǎn)的程序離不開(kāi)流程控制語(yǔ)句,Scala 提供了用于條件判斷的 if else和表示循環(huán)的 while。和 Java 中對(duì)應(yīng)的條件判斷語(yǔ)句不同,Scala 中的 if else是一個(gè)表達(dá)式,根據(jù)條件的不同返回相應(yīng)分支上的值。比如下面例子中求絕對(duì)值的程序,由于 Scala 中的 if else是一個(gè)表達(dá)式,所以不用像 Java 那樣顯式使用 return返回相應(yīng)的值。

使用 if else 表達(dá)式:

 
 
 
  1. def abs(n: Int): Int = if (n > 0) n else -n

和 Java 一樣,Scala 提供了用于循環(huán)的 while 語(yǔ)句,在下面的例子中,我們將借助 while 循環(huán)為整數(shù)列表求和。

使用 while 為列表求和:

 
 
 
  1. def sum(xs: List[Int]) = { 
  2. var total = 0 
  3. var index = 0 
  4. while (index < xs.size) { 
  5. total += xs(index) 
  6. index += 1 
  7. total 
  8. }

上述程序是習(xí)慣了 Java 或 C++ 的程序員想到的第一方案,但仔細(xì)觀察會(huì)發(fā)現(xiàn)有幾個(gè)問(wèn)題:首先,使用了 var定義變量,我們?cè)谇懊嬲f(shuō)過(guò),盡量避免使用 var。其次,這個(gè)程序太長(zhǎng)了,第一次拿到這個(gè)程序的人需要對(duì)著程序仔細(xì)端詳一會(huì):程序首先定義了兩個(gè)變量,并將其初始化為 0,然后在 index小于列表長(zhǎng)度時(shí)執(zhí)行循環(huán),在循環(huán)體中,累加列表中的元素,并將 index加 1,最后返回最終的累加值。直到這時(shí),這個(gè)人才意識(shí)到這個(gè)程序是對(duì)一個(gè)數(shù)列求和。

讓我們換個(gè)角度,嘗試用遞歸的方式去思考這個(gè)問(wèn)題,對(duì)一個(gè)數(shù)列的求和問(wèn)題可以簡(jiǎn)化為該數(shù)列的第一個(gè)元素加上由后續(xù)元素組成的數(shù)列的和,依此類(lèi)推,直到后續(xù)元素組成的數(shù)列為空返回 0。具體程序如下,使用遞歸,原來(lái)需要 9 行實(shí)現(xiàn)的程序現(xiàn)在只需要兩行,而且程序邏輯看起來(lái)更清晰,更易懂。

使用遞歸對(duì)數(shù)列求和:

 
 
 
  1. //xs.head 返回列表里的頭元素,即第一個(gè)元素 
  2. //xs.tail 返回除頭元素外的剩余元素組成的列表 
  3. def sum1(xs: List[Int]): Int = if (xs.isEmpty) 0 else xs.head + sum1(xs.tail)

有沒(méi)有更簡(jiǎn)便的方式呢?答案是肯定的,我們可以使用列表內(nèi)置的一些方法達(dá)到同樣的效果:

上述使用了規(guī)約操作。

規(guī)約操作是對(duì)容器的元素進(jìn)行兩兩運(yùn)算,將其規(guī)約為一個(gè)值。最常見(jiàn)的規(guī)約方式使 reduce,它接受一個(gè)二元函數(shù) f 作為參數(shù),首先將 f 作用在某兩個(gè)元素上并返回一個(gè)值,然后再將 f 作用在上一個(gè)返回值和容器的下一個(gè)元素上,再返回一個(gè)值,依次類(lèi)推,最后容器中的所有值會(huì)被規(guī)約為一個(gè)值。

 
 
 
  1. list map (_.toString) reduce((x,y)=>s"f($x,$y)")

上面這行代碼:先通過(guò) map 操作將List[Int] 轉(zhuǎn)化成 List[String],也就是把列表中的每個(gè)元素從 Int 類(lèi)型轉(zhuǎn)換成 String 類(lèi)型,然后對(duì)這個(gè)字符串進(jìn)行自定義規(guī)約,語(yǔ)句的執(zhí)行結(jié)果清楚地展示了 reduce的過(guò)程。

事實(shí)上,List 已經(jīng)為我們提供了 sum 方法,在實(shí)際應(yīng)用中,我們應(yīng)該使用該方法,而不是自己定義一個(gè)。作者只是希望通過(guò)上述例子,讓大家意識(shí)到 Scala 雖然提供了用于循環(huán)的 while 語(yǔ)句,但大多數(shù)情況下,我們有其他更簡(jiǎn)便的方式能夠達(dá)到同樣的效果。

四、如何運(yùn)行 Scala 程序?

在運(yùn)行方式上,Scala 又一次體現(xiàn)出了它的靈活性。它可以被當(dāng)作一種腳本語(yǔ)言執(zhí)行,也可以像 Java 一樣,作為應(yīng)用程序執(zhí)行。

作為腳本執(zhí)行:

  • 我們可以將 Scala 表達(dá)式寫(xiě)在一個(gè)文件里,比如 Hello.scala。在命令行中直接輸入 scala Hello.scala就可得到程序運(yùn)行結(jié)果。

Hello.scala 代碼:

 
 
 
  1. println("Hello Rickie!")

作為應(yīng)用程序執(zhí)行:

作為應(yīng)用程序執(zhí)行時(shí),我們需要在一個(gè)單例對(duì)象中定義入口函數(shù) main,經(jīng)過(guò)編譯后就可以執(zhí)行該應(yīng)用程序了。

 
 
 
  1. object HelloRickie { 
  2. def main(args: Array[String]): Unit = { 
  3. println("Hello Rickie!") 
  4. }

Scala 還提供了一個(gè)更簡(jiǎn)便的方式,直接繼承另一個(gè)對(duì)象 App,無(wú)需定義 main方法,編譯即可運(yùn)行。

五、結(jié)束語(yǔ)

本文為大家介紹了 Scala 的基本語(yǔ)法,相比 Java,Scala 的語(yǔ)法更加簡(jiǎn)潔,比如 Scala 的類(lèi)型推斷可以省略程序中絕大多數(shù)的類(lèi)型聲明,短小精悍的匿名函數(shù)可以方便的在函數(shù)之間傳遞,還有各種在 Scala 社區(qū)約定俗成的習(xí)慣,比如省略的分號(hào)以及函數(shù)體只有一條表達(dá)式時(shí)的花括號(hào),這一切都幫助程序員寫(xiě)出更簡(jiǎn)潔,更優(yōu)雅的程序。


網(wǎng)頁(yè)名稱(chēng):有趣的Scala語(yǔ)言:簡(jiǎn)潔的Scala語(yǔ)法
本文網(wǎng)址:http://m.5511xx.com/article/cdogiec.html