一、Scala 基础
- 变量
- 定义方法和函数
定义方法:
def func(x: Int, y: Int) = x + y
定义函数:
val fun = (x: Int, y: Int) => x + y
// 另外一种写法
val fun: (Int, Int) => Int = (x: Int, y: Int) => x + y
3. apply 方法
通常我们会在类的伴生对象中定义apply方法,当遇到类名(参数1,...参数n)时apply方法会被调用
object ApplyDemo {
def main(args: Array[String]) {
//调用了Array伴生对象的apply方法
//def apply(x: Int, xs: Int*): Array[Int]
//arr1中只有一个元素5
val arr1 = Array(5)
println(arr1.toBuffer)
//new了一个长度为5的array,数组里面包含5个null
var arr2 = new Array(5)
}
}
4. option 类型
在 Scala 中 Option 类型样例类用来表示可能存在或也可能不存在的值(Option 的子类有 Some 和 None)。Some 包装了某个值,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. 偏函数
被包在花括号内没有 match 的一组 case 语句是一个偏函数,它是 PartialFunction[A, B] 的一个实例,A 代表参数类型,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 高阶函数
2.1.1 闭包
参考文章:https://www.cnblogs.com/moonandstar08/p/5240312.html
2.1.2 将方法转换成函数
在 Scala 中,方法和函数是不一样的,最本质的区别是函数可以做为参数传递到方法中
但是方法可以被转换成函数,神奇的下划线又出场了
//定义一个方法
def method(x: nt) = x * 3
//神奇的下划线将方法转换成了函数
val fun = method _
//将函数传入 map 中
arr.map(fun)
2.1.3 柯里化
柯里化指的是将原来接受两个参数的方法变成新的接受一个参数的方法的过程
例子:
object Kelihua {
def main(args: Array[String]): Unit = {
val triple = mul(3)
val half = mul(0.5)
//柯里化如果没有第二个参数,就要用 _ 占位
// val triple = mul2(3)(_)
// val half = mul2(0.5)(_)
println(triple(14) + " " + half(14))
// 闭包也可以使用柯里化的方法调用
println(mul(3)(14))
}
// scala 的闭包
def mul(factor: Double) = (x: Double) => factor * x
// 柯里化的定义方式
def mul2(factor: Double)(x: Double) = factor * x
}
2.2 隐式转换和隐式参数
2.2.1 作用
隐式的对类的方法进行增强,丰富现有类库的功能
2.2.2 隐式转换函数
是指那种以implicit
关键字声明的带有单个参数的函数
举个例子:
- 先定义一个类:
class Girl(val name: String, var faceValue: Int, var age: Int)
- 下面要对 Girl 类进行增强,使她具有排序的功能
做法一:使用视图界定,ViewBound,需要传入一个隐式的函数
class Choosen[T <% Ordered[T]] {
def choose(x: T, y: T) = {
if (x > y) x else y
}
}
- 定义隐式方法,用来将 Girl 转换成 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 = {
// 导入隐式转换
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)
}
}
以上的例子还可以使用上下文界定实现,ContextBound,需要传入一个隐式的值
// 上下文界定
class Choosen[T : Ordering] {
def select(x: T, y: T) = {
val ord = implicitly[Ordering[T]]
if(ord.gt(x, y)) x else y
}
}
ContextBound 需要传入一个隐式值
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
}
}
}
抽象成公共方法,并结合使用隐式参数来实现
class Choosen[T] {
// 隐式参数,相当于ViewBound 视图界定
def choose(x: T, y: T)(implicit ord: T => Ordered[T]) = {
if (x > y) x else y
}
// 相当于传入一个隐式值,相当于 ContextBound
def select(x: T, y: T)(implicit ord : Ordering[T]) = {
if (ord.gt(x, y)) x else y
}
}