成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Scala中的if表達式和while循環(huán)

開發(fā) 后端
本文節(jié)選自Martin Odersky,Lex Spoon和Bill Venners所著,Regular翻譯的《Programming in Scala》的第七章。Scala是一種針對 JVM 將函數(shù)和面向對象技術組合在一起的編程語言。

if表達式

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

51CTO編輯推薦:Scala編程語言專題

  1. var filename = "default.txt" 
  2. if (!args.isEmpty)  
  3.  filename = args(0)  
這段代碼聲明了一個變量,filename,并初始化為缺省值。然后使用if表達式檢查是否提供給程序了任何參數(shù)。如果是,就把變量改成定義在參數(shù)列表中的值。如果沒有參數(shù),就任由變量設定為缺省值。

這段代碼可以寫得更好一點,因為就像第2章第三步提到過的,Scala的if是能返回值的表達式。代碼7.1展示了如何不使用任何var而實現(xiàn)前面一個例子同樣的效果:

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

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

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

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

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

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

盡可能尋找使用val的機會。它們能讓你的代碼既容易閱讀又容易重構。

while循環(huán)

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

  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)計算***公約數(shù)

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

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

代碼 7.3 用do-while從標準輸入讀取信息

while和do-while結構被稱為“循環(huán)”,不是表達式,因為它們不產(chǎn)生有意義的結果,結果的類型是Unit。說明產(chǎn)生的值(并且實際上是唯一的值)的類型為Unit。被稱為unit value,寫做()。()的存在是Scala的Unit不同于Java的void的地方。請在解釋器里嘗試下列代碼:

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

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

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

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

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

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

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

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

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

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

【相關閱讀】

  1. 學習Scala的重載方法和隱式轉換
  2. Scala的四種標識符構成方式
  3. Scala的私有字段和定義操作符
  4. Scala的從構造器:主構造器之外的構造器
  5. 在Scala中檢查先決條件、添加字段和自指向

責任編輯:book05 來源: Artima
相關推薦

2012-07-18 09:45:32

Java 8ScalaLambda

2009-07-21 14:38:08

Scalamatch表達式break和conti

2009-07-21 14:16:18

Scalafor表達式

2024-01-05 17:41:36

Rust編程循環(huán)

2024-03-25 13:46:12

C#Lambda編程

2009-12-29 10:22:51

Scala 2.8

2018-09-27 15:25:08

正則表達式前端

2009-07-21 14:30:38

Scalatry-catch

2011-05-30 16:11:46

Javascript

2014-01-05 17:41:09

PostgreSQL表達式

2011-03-14 14:02:55

Python

2009-07-09 09:51:07

Lambda表達式C#

2020-11-04 09:23:57

Python

2022-01-14 07:56:39

C#動態(tài)查詢

2010-09-10 15:20:11

SQL函數(shù)計算表達式

2010-11-16 14:53:02

Oracle游標表達式

2009-09-17 09:09:50

Lambda表達式Linq查詢

2021-03-24 13:17:41

編程循環(huán)語句Java

2020-12-18 09:05:13

算法單調(diào)棧

2010-04-28 18:17:16

Oracle CASE
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91美女在线观看 | 天天干天天爱天天 | 日韩av黄色| 全免费a级毛片免费看视频免费下 | 亚洲欧美激情精品一区二区 | 欧美精品在线观看 | 国产aⅴ精品| 伊人久久大香线 | 亚洲精品在线看 | 国产一区二区高清在线 | 久久精品视频12 | 拍戏被cao翻了h承欢 | 国产精品美女久久久久aⅴ国产馆 | 精品欧美一区二区三区久久久小说 | 欧美一区二区成人 | 亚洲精品大片 | 在线观看成人 | 天天综合91 | 中文字幕视频网 | 日韩精品一区二区三区中文字幕 | 伊人精品视频 | 成人网在线 | 精品欧美一区免费观看α√ | 中文字幕一区二区三区乱码图片 | 涩色视频在线观看 | 一区二区三区电影网 | www.一区二区三区 | 精品精品| 成人欧美一区二区三区在线观看 | av一区二区三区四区 | 国产成人a亚洲精品 | 日韩插插 | 亚洲精品18 | 亚洲视频一区二区三区四区 | 欧美一区二区三区在线播放 | 久久午夜视频 | 黄色片网站在线观看 | 亚洲 中文 欧美 日韩 在线观看 | 91 中文字幕 | 亚洲精品小视频在线观看 | 亚洲成人一区二区 |