2016年4月14日 星期四

[Scala 小學堂] Scala Gossic : 起步走 - 內建控制結構 (while 迴圈)

轉載自 這裡 
前言 : 
Scala 是一個可直譯、編譯、靜態、運行於 JVM 之上、可與 Java 互操作、融合物件導向編程特性與函式編程風格的程式語言. 從一些簡單的語法開始,了解 Scala 的許多特性,所以就算是起步走,東西也夠多了. 簡單的小程式可以使用 scala 指令,編譯的事就交給 scalac,編譯想快點就用 fsc. (Scala 官網), 運算式有傳回值,迴圈沒有,對了!Scala 沒有 break 與 continue. 

while 迴圈 : 
while 迴圈根據所指定的條件式來判斷是否執行迴圈本體,例如以下是個求最大公因數的程式 : 
- While1.scala 代碼 :
  1. println("Please input two int: ")  
  2. var m = readInt  
  3. var n = readInt  
  4.   
  5. while(n!=0) {  
  6.         var r = m%n  
  7.         m = n;  
  8.         n = r  
  9. }  
  10. println("GCD: "+m)  

如果迴圈本體只有一個陳述句,則 while 的 { } 可以省略不寫;while 迴圈為前測式迴圈,因為它在迴圈執行前就會進行條件判斷,而 do while 為後測式迴圈,它會先執行迴圈本體,然後再進行條件判斷,例如 : 
- While2.scala 代碼 :
  1. do {  
  2.         println("Input Number:")  
  3.         printf("Number is %s%n"if(readInt %2==0"Even" else "Odd")  
  4.         print("Continue?(yes/no)");  
  5. }while(readLine=="yes")  

這個程式會判斷使用者輸入數為奇數或偶數,並詢問是否繼續,如果輸入Yes則繼續,輸入No離開. 在 Scala 中,while 並不是運算式,因為它不會傳回運算的結果。不過若要更精確地說,while 傳回 (),類型是 Unit,稱之為單元值(Unit value),在 Scala 中,一個操作不需傳回任何值時就傳回 Unit,你沒辦法拿 Unit 作什麼事,所以傳回 Unit 其實就等同於沒有傳回值. 因為 while 不會有傳回值,所以使用 while 處理某件事時,經常伴隨著 var 的存在,如先前所說的,Scala 鼓勵你使用 val,因為 var 允許變數被重新設值,這使得演算不易被拆解為獨立的任務,追蹤變數值往往也會是件困難的事. 由於 while 往往伴隨著 var 的使用,因此 Scala 中鼓勵你將 while 迴圈的任務嘗試使用遞迴來解決,例如先前求最大公因數的例子,若可以定義為函式並使用遞迴,則可以改寫為以下(記得 if 是個運算式,所以可以有傳回值) : 
- GCD.scala 代碼 :
  1. def gcd(m: Int, n:Int): Int = if(n==0) m else gcd(n, m%n)  
  2. println("Input two number...")  
  3. println("GCD:" + gcd(readInt, readInt))  

在 Scala 中,指定運算也是不傳回值的操作,如果你熟悉 Java,有個在 Java 中很常的操作,在 Scala 中就行不通 : 
- 範例代碼 :
  1. var line = ""  
  2. while((line = readLine) != "") {  
  3.     println("Echo: " + line)  
  4. }  

這個片段很類似在 Java 讀取輸入的程式,你的目的是希望使用者直接按下Enter後(readLine 會傳回 "")離開程式,但這個片段在 Scala 中會有以下的警訊 : 
warning: comparing values of types Unit and java.lang.String using `!=' will always yield true
while((line = readLine) != "") {

這是因為指定運算的回傳結果會是 Unit,所以實際上,你的 while 迴圈等於是 : 
  1. while(() != "") {  
  2.     ...  
  3. }  
() != "" 的結果永遠會是 true,你等於是在寫無窮迴圈,所以程式並不會如你所願在按下 Enter 後結束. 

Supplement 
Tutorialspoint - Scala Loop Types 
起步走 - 內建控制結構 (if 運算式) 
起步走 - 內建控制結構 (for 運算式) 
起步走 - 內建控制結構 (while 迴圈) 
起步走 - 內建控制結構 (match 運算式) 

起步走 - 內建控制結構 (try 運算式)

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...