日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
Scala中的if表達(dá)式和while循環(huán)

if表達(dá)式

創(chuàng)新互聯(lián)建站主營(yíng)會(huì)澤網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,手機(jī)APP定制開(kāi)發(fā),會(huì)澤h5成都微信小程序搭建,會(huì)澤網(wǎng)站營(yíng)銷推廣歡迎會(huì)澤等地區(qū)企業(yè)咨詢

Scala的if如同許多其它語(yǔ)言中的一樣工作。它測(cè)試一個(gè)狀態(tài)并據(jù)其是否為真,執(zhí)行兩個(gè)分支中的一個(gè)。下面是一個(gè)常見(jiàn)的例子,以指令式風(fēng)格編寫:

編輯推薦:Scala編程語(yǔ)言專題

 
 
 
  1. var filename = "default.txt" 
  2. if (!args.isEmpty)  
  3.  filename = args(0)  

這段代碼聲明了一個(gè)變量,filename,并初始化為缺省值。然后使用if表達(dá)式檢查是否提供給程序了任何參數(shù)。如果是,就把變量改成定義在參數(shù)列表中的值。如果沒(méi)有參數(shù),就任由變量設(shè)定為缺省值。

這段代碼可以寫得更好一點(diǎn),因?yàn)榫拖竦?章第三步提到過(guò)的,Scala的if是能返回值的表達(dá)式。代碼7.1展示了如何不使用任何var而實(shí)現(xiàn)前面一個(gè)例子同樣的效果:

 
 
 
  1. val filename =  
  2.  if (!args.isEmpty) args(0)  
  3.  else "default.txt" 

代碼 7.1 在Scala里根據(jù)條件做初始化的慣例

這一次,if有了兩個(gè)分支。如果args不為空,那么初始化元素,args(0),被選中。否則,缺省值被選中。這個(gè)if表達(dá)式產(chǎn)生了被選中的值,然后filename變量被初始化為這個(gè)值。這段代碼更短一點(diǎn)兒,不過(guò)它的實(shí)際優(yōu)點(diǎn)在于使用了val而不是var。使用val是函數(shù)式的風(fēng)格,并能以差不多與Java的final變量同樣的方式幫到你。它讓代碼的讀者確信這個(gè)變量將永不改變,節(jié)省了他們掃描變量字段的所有代碼以檢查它是否改變的工作。

使用val而不是var的第二點(diǎn)好處是他能更好地支持等效推論:equational reasoning。在表達(dá)式?jīng)]有副作用的前提下,引入的變量等效于計(jì)算它的表達(dá)式。因此,無(wú)論何時(shí)都可以用表達(dá)式替代變量名。如,要替代println(filename),你可以這么寫:

 
 
 
  1. println(if (!args.isEmpty) args(0) else "default.txt") 

選擇權(quán)在你。怎么寫都行。使用val可以幫你安全地執(zhí)行這類重構(gòu)以不斷革新你的代碼。

盡可能尋找使用val的機(jī)會(huì)。它們能讓你的代碼既容易閱讀又容易重構(gòu)。

while循環(huán)

Scala的while循環(huán)表現(xiàn)的和在其它語(yǔ)言中一樣。包括一個(gè)狀態(tài)和循環(huán)體,只要狀態(tài)為真,循環(huán)體就一遍遍被執(zhí)行。代碼7.2展示了一個(gè)例子:

 
 
 
  1. def gcdLoop(x: Long, y: Long): Long = {  
  2.  var a = x  
  3.  var b = y  
  4.  while (a != 0) {  
  5.   val temp = a  
  6.   a = b % a  
  7.   b = temp  
  8.  }  
  9.  b  

代碼 7.2 用while循環(huán)計(jì)算***公約數(shù)

Scala也有do-while循環(huán)。除了把狀態(tài)測(cè)試從前面移到后面之外,與while循環(huán)沒(méi)有區(qū)別。代碼7.3展示了使用do-while反饋從標(biāo)準(zhǔn)輸入讀入的行記錄直到讀入空行為止的Scala腳本:

 
 
 
  1. var line = "" 
  2. do {  
  3.  line = readLine()  
  4.  println("Read: " + line)  
  5. } while (line != null)  

代碼 7.3 用do-while從標(biāo)準(zhǔn)輸入讀取信息

while和do-while結(jié)構(gòu)被稱為“循環(huán)”,不是表達(dá)式,因?yàn)樗鼈儾划a(chǎn)生有意義的結(jié)果,結(jié)果的類型是Unit。說(shuō)明產(chǎn)生的值(并且實(shí)際上是唯一的值)的類型為Unit。被稱為unit value,寫做()。()的存在是Scala的Unit不同于Java的void的地方。請(qǐng)?jiān)诮忉屍骼飮L試下列代碼:

 
 
 
  1. scala> def greet() { println("hi") }  
  2. greet: ()Unit  
  3. scala> greet() == ()  
  4. hi  
  5. res0: Boolean = true 

由于方法體之前沒(méi)有等號(hào),greet被定義為結(jié)果類型為Unit的過(guò)程。因此,greet返回unit值,()。這被下一行確證:比較greet的結(jié)果和unit值,(),的相等性,產(chǎn)生true。

另一個(gè)產(chǎn)生unit值的與此相關(guān)的架構(gòu),是對(duì)var的再賦值。比如,假設(shè)嘗試用下面的從Java(或者C或C++)里的while循環(huán)成例在Scala里讀取一行記錄,你就遇到麻煩了:

 
 
 
  1. var line = "" 
  2. while ((line = readLine()) != "") // 不起作用  
  3.  println("Read: "+ line)  

編譯這段代碼時(shí),Scala會(huì)警告你使用!=比較類型為Unit和String的值將永遠(yuǎn)產(chǎn)生true。而在Java里,賦值語(yǔ)句可以返回被賦予的那個(gè)值,同樣情況下標(biāo)準(zhǔn)輸入返回的一條記錄在Scala的賦值語(yǔ)句中永遠(yuǎn)產(chǎn)生unit值,()。因此,賦值語(yǔ)句“l(fā)ine = readLine()”的值將永遠(yuǎn)是()而不是""。結(jié)果,這個(gè)while循環(huán)的狀態(tài)將永遠(yuǎn)不會(huì)是假,于是循環(huán)將因此永遠(yuǎn)不會(huì)結(jié)束。

由于while循環(huán)不產(chǎn)生值,它它經(jīng)常被純函數(shù)式語(yǔ)言所舍棄。這種語(yǔ)言只有表達(dá)式,沒(méi)有循環(huán)。雖然如此,Scala仍然包含了while循環(huán),因?yàn)橛行r(shí)候指令式的解決方案更可讀,尤其是對(duì)那些以指令式背景為主導(dǎo)的程序員來(lái)說(shuō)。例如,如果你想做一段重復(fù)某進(jìn)程直到某些狀態(tài)改變的算法代碼,while循環(huán)可以直接地表達(dá)而函數(shù)式的替代者,大概要用遞歸實(shí)現(xiàn),或許對(duì)某些代碼的讀者來(lái)說(shuō)就不是那么顯而易見(jiàn)的了。

如,代碼7.4展示了計(jì)算兩個(gè)數(shù)的***公約數(shù)的替代方式。 給定同樣的值x和y,代碼7.4展示的gcd函數(shù)將返回與代碼7.2中g(shù)cdLoop函數(shù)同樣的結(jié)果。這兩種方式的不同在于gcdLoop寫成了指令式風(fēng)格,使用了var和while循環(huán),而gcd更函數(shù)式風(fēng)格,采用了遞歸(gcd調(diào)用自身)并且不需要var:

 
 
 
  1. def gcd(x: Long, y: Long): Long =  
  2.  if (y == 0) x else gcd(y, x % y)  

代碼 7.4 使用遞歸計(jì)算***公約數(shù)

通常意義上,我們建議你如質(zhì)疑var那樣質(zhì)疑你代碼中的while循環(huán)。實(shí)際上,while循環(huán)和var經(jīng)常是結(jié)對(duì)出現(xiàn)的。因?yàn)閣hile循環(huán)不產(chǎn)生值,為了讓你的程序有任何改變,while循環(huán)通常不是更新var就是執(zhí)行I/O??梢栽谥暗膅cdLoop例子里看到。在while循環(huán)工作的時(shí)候,更新了a和b兩個(gè)var。因此,我們建議你在代碼中對(duì)while循環(huán)抱有更懷疑的態(tài)度。如果沒(méi)有對(duì)特定的while或do循環(huán)較好的決斷,請(qǐng)嘗試找到不用它們也能做同樣事情的方式。

【相關(guān)閱讀】

  1. 學(xué)習(xí)Scala的重載方法和隱式轉(zhuǎn)換
  2. Scala的四種標(biāo)識(shí)符構(gòu)成方式
  3. Scala的私有字段和定義操作符
  4. Scala的從構(gòu)造器:主構(gòu)造器之外的構(gòu)造器
  5. 在Scala中檢查先決條件、添加字段和自指向

新聞標(biāo)題:Scala中的if表達(dá)式和while循環(huán)
網(wǎng)站鏈接:http://www.dlmjj.cn/article/coodsgc.html