一烛卧、Scala 基礎(chǔ)
- 變量
- 定義方法和函數(shù)
定義方法:
def func(x: Int, y: Int) = x + y
定義函數(shù):
val fun = (x: Int, y: Int) => x + y
// 另外一種寫法
val fun: (Int, Int) => Int = (x: Int, y: Int) => x + y
3. apply 方法
通常我們會在類的伴生對象中定義apply方法,當(dāng)遇到類名(參數(shù)1,...參數(shù)n)時(shí)apply方法會被調(diào)用
object ApplyDemo {
def main(args: Array[String]) {
//調(diào)用了Array伴生對象的apply方法
//def apply(x: Int, xs: Int*): Array[Int]
//arr1中只有一個(gè)元素5
val arr1 = Array(5)
println(arr1.toBuffer)
//new了一個(gè)長度為5的array肖方,數(shù)組里面包含5個(gè)null
var arr2 = new Array(5)
}
}
4. option 類型
在 Scala 中 Option 類型樣例類用來表示可能存在或也可能不存在的值(Option 的子類有 Some 和 None)冰悠。Some 包裝了某個(gè)值节槐,None 表示沒有值
package cn.itcast.cases
object OptionDemo {
def main(args: Array[String]) {
val map = Map("a" -> 1, "b" -> 2)
val v = map.get("b") match {
case Some(i) => i
case None => 0
}
println(v)
//更好的方式
val v1 = map.getOrElse("c", 0)
println(v1)
}
}
5. 偏函數(shù)
被包在花括號內(nèi)沒有 match 的一組 case 語句是一個(gè)偏函數(shù)操灿,它是 PartialFunction[A, B] 的一個(gè)實(shí)例,A 代表參數(shù)類型趾盐,B 代表返回類型庶喜,常用作輸入模式匹配
package cn.itcast.cases
object PartialFuncDemo {
def func1: PartialFunction[String, Int] = {
case "one" => 1
case "two" => 2
case _ => -1
}
def func2(num: String) : Int = num match {
case "one" => 1
case "two" => 2
case _ => -1
}
def main(args: Array[String]) {
println(func1("one"))
println(func2("one"))
}
}
二、scala 高級特性
2.1 高階函數(shù)
2.1.1 閉包
參考文章:https://www.cnblogs.com/moonandstar08/p/5240312.html
2.1.2 將方法轉(zhuǎn)換成函數(shù)
在 Scala 中救鲤,方法和函數(shù)是不一樣的久窟,最本質(zhì)的區(qū)別是函數(shù)可以做為參數(shù)傳遞到方法中
但是方法可以被轉(zhuǎn)換成函數(shù),神奇的下劃線又出場了
//定義一個(gè)方法
def method(x: nt) = x * 3
//神奇的下劃線將方法轉(zhuǎn)換成了函數(shù)
val fun = method _
//將函數(shù)傳入 map 中
arr.map(fun)
2.1.3 柯里化
柯里化指的是將原來接受兩個(gè)參數(shù)的方法變成新的接受一個(gè)參數(shù)的方法的過程
例子:
object Kelihua {
def main(args: Array[String]): Unit = {
val triple = mul(3)
val half = mul(0.5)
//柯里化如果沒有第二個(gè)參數(shù)本缠,就要用 _ 占位
// val triple = mul2(3)(_)
// val half = mul2(0.5)(_)
println(triple(14) + " " + half(14))
// 閉包也可以使用柯里化的方法調(diào)用
println(mul(3)(14))
}
// scala 的閉包
def mul(factor: Double) = (x: Double) => factor * x
// 柯里化的定義方式
def mul2(factor: Double)(x: Double) = factor * x
}
2.2 隱式轉(zhuǎn)換和隱式參數(shù)
2.2.1 作用
隱式的對類的方法進(jìn)行增強(qiáng)斥扛,豐富現(xiàn)有類庫的功能
2.2.2 隱式轉(zhuǎn)換函數(shù)
是指那種以implicit
關(guān)鍵字聲明的帶有單個(gè)參數(shù)的函數(shù)
舉個(gè)例子:
- 先定義一個(gè)類:
class Girl(val name: String, var faceValue: Int, var age: Int)
- 下面要對 Girl 類進(jìn)行增強(qiáng),使她具有排序的功能
做法一:使用視圖界定丹锹,ViewBound稀颁,需要傳入一個(gè)隱式的函數(shù)
class Choosen[T <% Ordered[T]] {
def choose(x: T, y: T) = {
if (x > y) x else y
}
}
- 定義隱式方法,用來將 Girl 轉(zhuǎn)換成 Ordered[Girl]
object MyPreDef {
// 隱式方法
implicit def girlToOrdered(g: Girl) = new Ordered[Girl] {
override def compare(that: Girl) = {
if (g.faceValue == that.faceValue) {
g.age - that.age
} else {
g.faceValue - that.faceValue
}
}
}
}
- 測試成功
object Choosen {
def main(args: Array[String]): Unit = {
// 導(dǎo)入隱式轉(zhuǎn)換
import MyPreDef._
val ch = new Choosen[Girl]
val g1 = new Girl("liuyan", 80, 23)
val g2 = new Girl("JULIA", 100, 18)
println(ch.choose(g1, g2).name)
}
}
以上的例子還可以使用上下文界定實(shí)現(xiàn)卷仑,ContextBound峻村,需要傳入一個(gè)隱式的值
// 上下文界定
class Choosen[T : Ordering] {
def select(x: T, y: T) = {
val ord = implicitly[Ordering[T]]
if(ord.gt(x, y)) x else y
}
}
ContextBound 需要傳入一個(gè)隱式值
implicit val grilToOrdering = new Ordering[Girl]{
override def compare(x: Girl, y: Girl) = {
if (x.faceValue == y.faceValue) {
x.age - y.age
} else {
x.faceValue - y.faceValue
}
}
}
抽象成公共方法麸折,并結(jié)合使用隱式參數(shù)來實(shí)現(xiàn)
class Choosen[T] {
// 隱式參數(shù)锡凝,相當(dāng)于ViewBound 視圖界定
def choose(x: T, y: T)(implicit ord: T => Ordered[T]) = {
if (x > y) x else y
}
// 相當(dāng)于傳入一個(gè)隱式值,相當(dāng)于 ContextBound
def select(x: T, y: T)(implicit ord : Ordering[T]) = {
if (ord.gt(x, y)) x else y
}
}