scala初體驗3——控制


                                                                    控制結構和函數
1.關於返回值
在scala任何的函數、表達式、方法都有返回值(有些情況類似與java的void,所以scala創立了unit這個標識符來表示特殊的返回值)。
(1){}的返回值以其中最后一個表達式的返回值為准,eg:
{val r=1;r+1},該表達式的返回值就是2,因為r+1的返回值為2;
(2)賦值表達式的返回值為unit,eg:
val k=5,該表達式的值為unit的形式;
注意:在給變量賦值的時候,注意負數的書寫: var t=-1 ,這種寫法可能會報錯,必須將負數符號與等號加一個空格。

2.選擇表達式的值 (1)Scala 包含 if/else 的結構 與 Java 或 C++中的相同。但是在scala中if/ else表達式是有值的——稱為if或else表達式的值。例如: val test=1 if(test>0) 1 else -1 語句運行后,輸出: res14: Int = 1 其中,1就是這個表達式的值,你可以將這個值賦予其它的變量: val s = if (x > 0) 1 else -1 ,當然也可以寫成:if (x > 0)s= 1 else s=-1,但是第一種寫法比較好,因為第一種寫法可以用來初始化val類型的變量,
而第二種方法中的s只能是var類型的。同時在java中有一個式子和它的功能相同:x > 0 ? 1 : -1;
(2)在scala中每個表達式都有它們的類型, if (x > 0) 1 else -1表達式的類型就是Int,當然if/else表達式也有混合值,比如:
if (x > 0) 1 else“good”;
但是它們的返回值有意個共同的超類:Any。也就是Any相當於萬金油,類似於java中的Objetc。 如果表達式缺少了else,它怎樣取值呢?在scala中,表達式總是要有一個值的,面對這個情況,scala創造了unit類型,這類似與java中的
voido類型,所以 if (x > 0) 1 可能會返回unit。


3.輸入與輸出
scala中常用的輸出為:
print("hello ")或println(2),只要對java多少有點了解的人都知道,這里跟java中的相似,就是少了System.out;
另外還可一寫成C++中的方式:printf()等。

4.循環
(1)常用循環
java中的循環語句scala中while關鍵字可以直接拿過來用,要注意的是,scala不支持傳統的for循環。但是要想更好地學習scala,理解函數
式編程,就要學會scala中特有的循環方式:
     for (i <- 1 to n)
          r = r * i
下面為大家介紹該語句的原理:
1 to n 為 1.to(n),該語句返回一個集合,該集合包含1到n之間的所有整數,優點類似與arraylist<Integer>這種方式。其中“1 to n”也可寫
成1 untils n+1的方式,都是返回1到n之間的所有整數集合。另外,只要是集合類型都可以用於該方法中,eg:
var sum = 0
for (ch <- "Hello") sum += ch
"Hello"在這里被認為字符集合。
補充:

(2)雙重循環
雙重循環可以使用java中循環疊加的方式實現,也可使用如下方式實現:
for (i <- 1 to 3; j <- 1 to 3) print((10 * i + j) + " ")
// Prints 11 12 13 21 22 23 31 32 33

在循環體中,還可以嵌套處理語句
for (i <- 1 to 3; j <- 1 to 3 if i != j) print((10 * i + j) + " ")
// Prints 12 13 21 23 31 32

for (i <- 1 to 3; from = 4 - i; j <- from to 3) print((10 * i + j) + " ")
// Prints 13 22 23 31 32 33

for與yeild循環
for (i <- 1 to 10) yield i % 3
// 返回 Vector(1, 2, 0, 1, 2, 0, 1, 2, 0, 1)
加入yeild關鍵字,會返回一組集合類型,這種形式的循環被稱作for 理解。


(3)跳出循環
在scala中,並不提供break或continue等語句,如果要跳出循環,有以下語句:
1. 使用一個布爾控制變量代替——while循環中
2. 使用return
3. 使用Breaks對象中的break方法:
import scala.util.control.Breaks._
breakable {
for (...) {
if (...) break; // Exits the breakable block
...
}
}

注意:在scala常常避免使用for循環(這是for循環在scala中的實現形式決定的),會采用其它方式;另外for循環和while循環的性能差距比較大
scala>
  var start = System.currentTimeMillis();
  var total = 0;for(i <- 0 until 100000) { total += i };
  var end = System.currentTimeMillis();
  println(end-start);
  println(total);
114
scala>
scala< 
  var start = System.currentTimeMillis();
  var total = 0;var i=0;while(i < 100000) { i=i+1;total += i };
  var end = System.currentTimeMillis();
  println(end-start);
  println(total);
8


5.函數
除了方法外,scala還具有函數元素;scala與java的方法要通過類的對象來調用,在java中要實現函數的功能就要依附於類而存在。我們說過
在scala的世界中,函數也是對象,而且是這個世界的一等公民,所以函數定義后可以像對象那樣使用,eg:
def abs(x: Double) = if (x >= 0) x else -x
你必須指定所有參數的類型. 如果函數不是遞歸的(程序調用自身的編程技巧稱為遞歸,遞歸函數必須要有返回值,並知道返回值的類型),所以你不
必規定返回類型,scala編譯器從等號右邊的表達式來決定返回值的類型;
如果函數比較復雜,則使用塊來標識函數,eg:
def fac(n : Int) = {
var r = 1
for (i <- 1 to n) r = r * i
r
},函數的返回值就是塊的返回值;上面代碼的返回值為r,因為塊的最后一句是r,r的返回值就是r的值本身;
對於遞歸函數,必須規定返回值,eg:
def fac(n: Int): Int = if (n <= 0) 1 else n * fac(n - 1)
scala中函數與方法的區別
是否帶等號的就是函數,不帶等號的就是方法?
否,函數若沒有返回值可以不寫等號;


6.方法

7.慵懶變量
如果在val類型的變量前面加入lazy標識符,則改變量的初始化就會放在使用它的時候,這樣可以在初期的初始化過程中,節省時間,方便系統的啟動
,在另一種意義上說這是一種負載均衡,eg:
lazy val words =“word”,只有在使用時,words才會被真正賦值;

8.異常
在scala中,異常的定義與java中相似,不過拋出異常操作的類型為nothing,捕獲異常處理使用特殊的模式匹配語法:

try {
process(new URL("http://horstmann.com/fred-tiny.gif"))
} catch {
case _: MalformedURLException => println("Bad URL: " + url)
case ex: IOException => ex.printStackTrace()
}























免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM