简介
在前几章中,我们已经了解到了Scala的基本用法,主要包含基本的语法、基本的数据结构和面向对象的特性,以及Scala的部分高级特性:模式匹配、样例和函数,如果不了解这些,可以查看前几章大数据知识:快学Scala(二)模式匹配和样例类以及高级性质。本章将会介绍Scala 的高级特性,高阶函数和隐私转换。
高阶函数
基本概念
Scala混合了面向对象和函数式的特性,我们通常将可以做为参数传递到方法中的表达式叫做函数。在函数式编程语言中,函数是“头等公民”,高阶函数包含:作为值的函数、匿名函数、闭包、柯里化等等。
作为值的函数
可以像任何其他数据类型一样被传递和操作的函数,每当你想要给算法传入具体动作时这个特性就会变得非常有用。
定义函数时格式:val 变量名=(输入参数类型和个数)=>函数实现和返回值类型和个数
“=”表示将函数赋给一个变量
“=>”左面表示输入参数名称、类型和个数,右边表示函数的实现和返回值类型和参数个数
匿名函数
在Scala中,你不需要给每一个函数命名,没有将函数赋给变量的函数叫做匿名函数。
由于Scala可以自动推断出参数的类型,所有可以写的跟精简一些。
还记得神奇的下划线吗?这才是终极方式
将方法转化为函数
在Scala中,方法和函数是不一样的,最本质的区别是函数可以做为参数传递到方法中
但是方法可以被转换成函数,神奇的下划线又出场了
柯里化
柯里化指的是将原来接受两个参数的方法变成新的接受一个参数的方法的过程。
package cn.edu.hust.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)
}
}
隐式转化和隐式参数
概念
隐式转换和隐式参数是Scala中两个非常强大的功能,利用隐式转换和隐式参数,你可以提供优雅的类库,对类库的使用者隐匿掉那些枯燥乏味的细节。
作用
隐式的对类的方法进行增强,丰富现有类库的功能
隐式转化函数
是指那种以implicit关键字声明的带有单个参数的函数
实例代码:
import java.io.File
import scala.io.{ Source}
class RichFile(from:File)
{
def read():String=Source.fromFile(from.getPath).mkString
}
object context{
val y:Int=200;
//隐士转化方法,将java中file没有的read方法自定义个类,进行包装,然后是想read方法
implicit def file2RichFile(file:File)=new RichFile(file)
}
class implicitly {
// 隐式转换
def func(x:Int)=(y:Int)=>
{
x*y
}
//
def func1(x:Int)(y:Int)={
x*y
}
//柯里化
def func3(x:Int)(implicit y:Int=100): Int =
{
x*y
}
}
object implicitly extends App{
val a=new implicitly
val result=a.func3(3)
//这里隐式转化
import context._
val file=new File("/Users/youyujie/Downloads/word.txt")
val content=file.read
val t=Source.fromFile("/Users/youyujie/Downloads/word.txt").mkString
println(result)
//println(file.getPath)
println(content)
println(t)
}
隐式转化
package cn.edu.hust.ordering
class Boy(val name:String, val faceValue:Int) {
}
package cn.edu.hust.ordering class Chooser[T:Ordering] { def choose(first:T,second:T):T={ val ord=implicitly[Ordering[T]] if(ord.gt(first,second)) first else second } }
package cn.edu.hust.ordering object context { //定义比较的规则 // implicit def object2Ordered(b:Boy)=new Ordered[Boy] // { // override def compare(that: Boy):Int = { // b.faceValue-that.faceValue // } // } implicit object object2Ordering extends Ordering[Boy]{ override def compare(x: Boy, y: Boy): Int = { x.faceValue-y.faceValue } } }
package cn.edu.hust.ordering import context._ object app { def main(args: Array[String]): Unit = { //这里需要引入比较规则 val c=new Chooser[Boy] val boy1=new Boy("jim",90) val boy2=new Boy("tom",99) val result=c.choose(boy1,boy2) println(result.name) } }
Scala中的范型
package cn.edu.hust.generic
class Boy(val name:String,val faceValue:Int){
}
package cn.edu.hust.generi
class Chooser[T<%Ordered[T]]
{
def choose(first:T,second:T):T={
if(first>second) first else second
}
}
package cn.edu.hust.generic object context { //定义比较的规则 implicit def object2Ordered(b:Boy)=new Ordered[Boy] { override def compare(that: Boy):Int = { b.faceValue-that.faceValue } } }
package cn.edu.hust.generic import cn.edu.hust.generi.Chooser import context._ object app { def main(args: Array[String]): Unit = { //这里需要引入比较规则 val c=new Chooser[Boy] val boy1=new Boy("jim",90) val boy2=new Boy("tom",99) val result=c.choose(boy1,boy2) println(result.name) } }