2018-12-10 16:31:28
1.高级函数
1.1. 概念
Scala混合了面向对象和函数式编程的特性,我们通常将可以做为参数传递到方法中的表达式叫做函数
1.2. 作为值的函数
可以像任何其他数据类型一样被传递和操作的函数,每当你想要给算法传入具体动作时这个特性就会变得非常有用。
定义函数时格式:val 变量名 = (输入参数类型和个数) => 函数实现和返回值类型和个数
“=”表示将函数赋给一个变量
“=>”左面表示输入参数名称、类型和个数,右边表示函数的实现和返回值类型和参数个数
val arr = Array(1,2,3,4,5) val fun1 = (x:Int) => x * 2 //定义一个函数并将函数赋给变量fun1 val res = arr.map(fun1) //将函数作为参数传入map方法中
1.3. 匿名函数
在Scala中,你不需要给每一个函数命名,没有将函数赋给变量的函数叫做匿名函数
//直接将匿名函数传入到map方法中,效果和前面一样,比较精简一些 val res = arr.map((x:Int) => x * 2)
由于scala可以自动推断出参数的类型,所以可以写的精简一些
val res = arr.map(x => x * 2) //神奇的下划线 val res = arr.map(_*2)
1.4. 将方法转换成函数
在Scala中,方法和函数是不一样的,最本质的区别是函数可以做为参数传递到方法中
但是方法可以被转换成函数,神奇的下划线又出场了
//定义一个方法 def m(x:Int) = x * 3 //神奇的下划线将方法转换成了函数 val fun2 = m _ //将函数传入map方法中 val res = arr.map(fun2)
1.5. 柯里化
柯里化指的是将原来接收两个参数列表的方法或函数变成新的一个参数列表的方法或函数的过程
//一个比较奇怪的方法,看起来即像方法又像函数 def m(x:Int) = (y:Int) => x * y //将一个参数3传进函数后,彻底变成了一个函数val func = (y:Int) => 3 * y val func = m(3) //然后在调用这个函数并传递第二个参数,得到最终结果 val res1 = func(5) //简写为 def m(x:Int)(y:Int) = x * y val res = m(3)(5)
1.6. 例子
package com.qf.scala object FunDemo { def main(args: Array[String]) { def f2(x: Int) = x * 2 val f3 = (x: Int) => x * 3 val f4: (Int) => Int = { x => x * 4 } val f4a: (Int) => Int = _ * 4 val f5 = (_: Int) * 5 val list = List(1, 2, 3, 4, 5) var new_list: List[Int] = null //第一种:最直观的方式 (Int) => Int //new_list = list.map((x: Int) => x * 3) //第二种:由于map方法知道你会传入一个类型为(Int) => Int的函数,你可以简写 //new_list = list.map((x) => x * 3) //第三种:对于只有一个参数的函数,你可以省去参数外围的() //new_list = list.map(x => x * 3) //第四种:(终极方式)如果参数在=>右侧只出现一次,可以使用_ new_list = list.map(_ * 3) new_list.foreach(println(_)) var a = Array(1,2,3) a.map(_* 3) } }
2. 隐式转换和隐式参数
2.1. 概念
隐式转换和隐式参数是Scala中两个非常强大的功能,利用隐式转换和隐式参数,你可以提供优雅的类库,对类库的使用者隐匿掉那些枯燥乏味的细节。
2.2. 作用
隐式的对类的方法进行增强,丰富现有类库的功能
2.3. 隐式转换函数
是指那种以implicit关键字声明的带有单个参数的函数
package com.qf.impli import java.io.File import scala.io.Source //隐式的增强File类的方法 class RichFile(val from: File) { def read = Source.fromFile(from.getPath).mkString } object RichFile { //隐式转换方法 implicit def file2RichFile(from: File) = new RichFile(from) } object MainApp{ def main(args: Array[String]): Unit = { //导入隐式转换 import RichFile._ //import RichFile.file2RichFile println(new File("c://words.txt").read) } } package com.qf.scala import java.awt.GridLayout object ImplicitContext{ //implicit def girl2Ordered(g : Girl) = new Ordered[Girl]{ // override def compare(that: Girl): Int = if (g.faceValue > that.faceValue) 1 else -1 //} implicit object OrderingGirl extends Ordering[Girl]{ override def compare(x: Girl, y: Girl): Int = if (x.faceValue > y.faceValue) 1 else -1 } } class Girl(var name: String, var faceValue: Double){ override def toString: String = s"name : $name, faveValue : $faceValue" } //class MissRight[T <% Ordered[T]](f: T, s: T){ // def choose() = if(f > s) f else s //} //class MissRight[T](f: T, s: T){ // def choose()(implicit ord: T => Ordered[T]) = if (f > s) f else s //} class MissRight[T: Ordering](val f: T, val s: T){ def choose()(implicit ord: Ordering[T]) = if(ord.gt(f, s)) f else s } object MissRight { def main(args: Array[String]) { import ImplicitContext.OrderingGirl val g1 = new Girl("yuihatano", 99) val g2 = new Girl("jzmb", 98) val mr = new MissRight(g1, g2) val result = mr.choose() println(result) }