筆記的整理主要針對Scala對比Java的新特性;shell
一、if表達式數組
if表達式是有結果返回的。app
val a= if (5>2) 「你好」 else 1函數
a的值爲if表達式返回值爲 「你好」優化
二、while表達式scala
while表達式是沒有返回值的(返回值爲 Unit),在scala中避免使用,一般都須要與var結合使用對象
三、for表達式blog
枚舉集合遍歷遞歸
val a = Array(1,2,3,4,5,6)get
for (i <- a) println(i)
以上for表達式遍歷的語法成爲發生器,不只僅只是適合Array也適合其它集合類;
for表達式中 to 與 until的區別:to包含上限,until不包含上限;
遍歷過濾
for (i <- a if i>3) println(i)
if i>3稱爲發生器i <- a 的守衛,主要用於對發生器產生的數據進行過濾;
嵌套枚舉
for (i <- 0 to 5 if i>1 ;j <- 5 to 10 if j<9 ) println("i:"+i+",j:"+j)
這裏有兩個發生器,每一個發生器都帶有一個守衛。
執行的順序爲:先對將 i 賦值爲一個合法的值(即知足區間在0~5之間且i大於1),而後依次完成對 j 合法值(即知足區間在5~10之間且 j小於9)的全部遍歷,而後對 i 進行下一個合法值的遍歷賦值,再重複對 j合法值的全部遍歷,後面的過程以此類推;
產生新集合結果
val a = for (i <- 0 to 10 if i>5) yield i
for-yield語法:for (表達式) yield{循環體}
四、本地函數
特色:在方法中定義的方法,且本地方法僅在包含它代碼塊中可見(相似局部變量);
五、頭等函數
把函數當值傳遞(如同變量),函數字變量被編譯進類,並在運行期實例化爲函數值。所以函數自變量與值的區別在於函數自變量存在於源碼,而函數值作爲對象存在於運行期(相似類與對象之間的關係);
函數自變量的構成包含括號、參數列別、右箭頭和函數體。如:(x:Int) => x+1 ; 右箭頭左邊爲括號很參數,右邊爲函數體
當編譯器能推斷出參數類型時,參數類型能夠省略:
var v = Array(1,2,3,4,5)
v.foreach(x => println(x+1))
六、佔位符
把下畫線當作一個或更多參數的佔位符,只要每一個參數在函數字面量內僅出現一次。
例如:
scala> v.filter(_ > 0)
res0: Array[Int] = Array(1, 3, 7)
七、部分應用函數
用單個下劃線替換整個參數列表;
例如:
scala> def add (a:Int,b:Int) = a+b
add: (a: Int, b: Int)Int
scala> val sum = add _
sum: (Int, Int) => Int = <function2>
scala> sum(1,2)
res1: Int = 3
sum變量指向一個函數值對象,該函數值依照部分應用函數表達式add _,自動產生的類的一個實例,編譯器產生的類有一個apply方法帶兩個參數,參數的個數有add _表達式缺乏的參數數量肯定;
另外一種表現形式(轉換函數值):
scala> def add(a:Int,b:Int) = a+b
add: (a: Int, b: Int)Int
scala> val sum = add(2,_:Int)
sum: Int => Int = <function1>
scala> sum(2)
res2: Int = 4
注意:一個省略全部參數的偏程序表達式(如:add _),且在代碼的某個地方正須要一個函數,能夠去掉下劃線使表達式更簡潔。如:scala> v.foreach(println)
八、可變參數
容許客戶向函數傳入可變長度參數列表,若想要標註一個重複參數,可在參數的類型以後放一個星號。
例1:
scala> def echo (args:String*)=
| for (arg <- args)println(arg)
echo: (args: String*)Unit
scala> echo()
scala> echo("hello","world")
hello
world
例2:
scala> var arr = Array("hello","world","chenx")
arr: Array[String] = Array(hello, world, chenx)
scala> def echo (args:String*)=for(arg <- args) println(arg)
echo: (args: String*)Unit
scala> echo(arr:_*)
重複參數的類型是聲明參數類型的數組,當參數類型爲一個合適類型的數組時,須要在數組參數後添加一個冒號和一個_*符號。
九、尾遞歸
方法的最後一個動做是調用本身的函數稱爲尾遞歸。Scala對尾遞歸的狀況進行了優化,比基於循環的實現更優美很簡明,由於無需付出任何運行期開銷,且遞歸必須是直接的。
注:-g:notailcalls 參數傳遞給scala shell 或者scalac編譯器,可用來跟蹤堆棧信息。
十、柯里化
對柯里化的理解能夠爲根據方法參數的個數,對方法進行拆解,如:def f(a:Int,b:Int)=a+b 轉換爲 def f(a:Int)(b:Int)=a+b
例1:
scala> def f(a:Int)(b:Int)=a+b
f: (a: Int)(b: Int)Int
scala> val t = f(1)_
t: Int => Int = <function1>
scala> t(2)
res0: Int = 3
例2:
scala> def f(a:Int)=(b:Int)=>a+b
f: (a: Int)Int => Int
scala> val t=f(1)
t: Int => Int = <function1>
scala> t(2)
res1: Int = 3
十一、控制抽象
在傳入一個參數時,用花括號替代小括號的機制。當參數爲函數字面量時讓方法的調用更像控制抽象;
例:
scala> def f(msg:String)(op:String => Unit){
| op(msg)}
f: (msg: String)(op: String => Unit)Unit
scala> f("123456"){println(_)}
123456
該例中是將def f(msg:String,op:String => Unit)柯里化爲def f(msg:String)(op:String => Unit),使其在調用函數字面量時能使用花括號,最後的println(_)也能夠替換爲 t => println(t),其中t爲參數可任意命名;
十二、傳名參數應用
做用:在匿名函數基礎上爲函數命名;
例:
scala> def f(op:() => Boolean){
| if (op())
| println("OK")
| else
| println("ERROR")
| }
f: (op: () => Boolean)Unit
scala> f(() => 5>3)
OK