Scala for the impatient: ch2
val s= if (x>0) 1 else -1
val s= if (x>0) "positive" else -1
此為公共超類型 (型態為Any)
if (x>0) 1
- 若為 else的結果,仍會回傳一個類型為Unit的(無有用值,void in JAVA,意即 if (x>0) 1 else ()
printf("hello, %s! you're %d years old.\n","andy",25)
- C格式的字串符
for (i in 0 until s.length)是在0至(n-1)的區間,意即不包含上限值
var sum=0; for (ch <- "hello") sum+=ch
若要退出循環,建議使用
- Boolean型控制變量
- 使用嵌套件函數
- 使用breaks對象中的break方法:
import scala.util.control.Break._ (但盡量避免用此方法) 高級for循環
for(i <- 1 to 2; j<- 1 to 3 if i!=j ) print((10*i+j)+ " ")
- 可多生成器,又可帶一個判斷(守衛)
for(i <- 1 to 3; from=4-i; j <- from to 3) print((10*i+j)+" ")
- 可以任意定義循環
for(i <- 1 to 10) yield i % 3
- 以 yield開始,再循環構造一個集合,每次迭代生成集合的一個值
- 此循環稱為for推導式
- 跑出來的結果會變成一個vector
盡量不要使用return,因為會使用大量匿名函數。把return當作是函數版的break
對於遞迴函數,必須對指定返回類型
能夠推斷遞迴函數類型的算法為Hindley-Milner
變長參數
def sum(args:Int*)={ var result=0 for (arg<-args) result +=arg result } val x= sum(111,2,3,4,5)
如果是傳入區間(希望變數區間當作參數序列處理,則需追加:_*)
val s= sum(1 to 5:_*)
如果函數沒有回傳值,則回傳類型為Unit,此函數又被稱為「procedure」
若不返回任何回傳值,可以省去=號
def box(s:String) {...}
但還是建議寫
def box(s:String):Unit ={...}
當變數被宣告為lazy時,它的初始化會被延遲到首次對他取值時。
lazy val words= scala.io.Source.fromFile("/Users/apple/Desktop/sss.txt").mkString
可以把懶值當作是介於val和def的中間狀態
val word= ... //定義時就取值
val lazy word= ... //在word被首次使用時取值
def word=...//每次呼叫word時取值
每次訪問懶值時會調用某個方法來檢查該值是否被初始化,因此會有額外開銷。
異常
var in = new URL("http://4.bp.blogspot.com/-s3DB3ryqocE/UvvhsovCC7I/AAAAAAAANnI/EENAw5YFXPE/s1600/lingerie+forever+(5).jpg").openStream()
try{ in.toString() }catch{ case _: ... case er: ... } finally{ in.close() } finally無論try有無拋出異常都會執行 try/catch通常是處理異常 try/finally是異常沒被處理形況下執行某種動作(e.g. 清理工作)