博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
6.Scala-高阶函数
阅读量:5232 次
发布时间:2019-06-14

本文共 3681 字,大约阅读时间需要 12 分钟。

第6章 高阶函数

6.1 作为参数的函数

函数作为一个变量传入到另一个函数中,那么该作为参数的函数的类型是:function1,即:

(参数类型)=> 返回值

//6.1 作为参数的函数def plus(x: Int) = 3 + xval result1 = Array(1, 2, 3, 4).map(plus(_))println(result1.mkString(","))

 

尖叫提示:带有一个参数的函数的类型是function1,带有两个参数的是function2,以此类推。

 

笔记:

//6.1 作为参数的函数def match1(): Unit = {  def plus(x: Int) = 3 + x  val result1 = Array(1, 2, 3, 4).map(plus(_))  println(result1.mkString(",")) //4,5,6,7}match1()

 

 

6.2 匿名函数

即没有名字的函数,可以通过函数表达式来设置匿名函数。

val triple = (x: Double) => 3 * x println(triple(3))//使用方法:Array(3.14, 1.42, 2.0).map(triple)//包含在()中Array(3.14, 1.42, 2.0).map((x: Double) => 3 * x)// 包含在{}中Array(3.14, 1.42, 2.0) map { (x: Double) => 3 * x }

 

笔记:

//6.2 匿名函数def match2(): Unit = {  val triple = (x: Double) => 3 * x  println(triple(3)) //9.0  //使用方法:  println(Array(3.14, 1.42, 2.0).map(triple).mkString(", ")) //9.42, 4.26, 6.0  //包含在()中  println(Array(3.14, 1.42, 2.0).map((x: Double) => 3 * x).mkString(", "))  // 包含在{}中  println(Array(3.14, 1.42, 2.0) map { (x: Double) => 3 * x } mkString(", "))}match2()

 

 

 

 

 

 

 

6.3 高阶函数

能接受函数作为参数的函数,叫做 高阶函数。
1)高阶函数的使用
def highOrderFunction1(f: Double => Double) = f(10)def minus7(x: Double) = x -7val result2 = highOrderFunction1(minus7)println(result2)
 
2)高阶函数同样可以返回函数类型
def minusxy(x: Int) = (y: Int) => x - yval result3 = minusxy(3)(5)println(result3)

 

 

 

 

 

 

 

6.4 参数(类型)推断

// 传入函数表达式valueAtOneQuarter((x: Double) => 3 * x)// 参数推断省去类型信息valueAtOneQuarter((x) => 3 * x)// 单个参数可以省去括号valueAtOneQuarter(x => 3 * x)// 如果变量旨在=>右边只出现一次,可以用_来代替valueAtOneQuarter(3 * _)

 

 

 

 

 

 

6.5 闭包

闭包就是一个函数把外部的那些不属于自己的对象也包含(闭合)进来了。
def minusxy(x : Int) = (y : Int) => x - yprintln(minusxy(10)(20))

 这就是一个闭包

 
1) 匿名函数(y : Int) => x - y 嵌套在函数 minusxy 中。
2) 匿名函数(x : Int) => x - y 使用了外部变量、mulBy 的局部变量 x。不是全局变量
3) 函数 minusxy 返回了引用局部变量的匿名函数。 

再举一个例子:

def minusxy(x: Int) = (y: Int) => x - yval f1 = minusxy(10)val f2 = minusxy(10)println(f1(3) + f2(3))

 

此处 f1,f2 这两个函数就叫闭包 。

 

 

 

 

6.6 柯里化

函数编程中,接受多个参数的函数都可以转化为接受单个参数的函数,
这个转化过程就叫柯里化,柯里化就是证明了函数只需要一个参数而已。
 
1)柯里化示例
// 传统定义两个参数def mul(x:Int, y: Int) = x * yprintln(mul(6,7))// 柯里化定义,使用到了闭包def mulOneAtATime(x: Int) = (y: Int) => x * yprintln(mulOneAtATime(6)(7))// Scala 中可以简写def mulOneAtATime(x: Int)(y: Int) = x * yprintln(mulOneAtATime(10)(8))

 

2)柯里化的应用

比较两个字符串再忽略大小写的情况下是否相等,注意,这里是两个任务:

1、全部转大写(或小写)

2、比较是否相等

针对这两个操作,我们用一个函数去处理的思想,其实无意间也变成了两个函数处理的思想。

示例如下:

val a = Array("Hello", "World")val b = Array("hello", "world")// def corresponds[B](that: GenSeq[B])(p: (A,B) => Boolean): Booleanprintln(a.corresponds(b)(_.equalsIgnoreCase(_)))

 

corresponds 函数的定义使用了柯里化
源码如下:
def corresponds[B](that: GenSeq[B])(p: (A,B) => Boolean): Boolean = {    val i = this.iterator    val j = that.iterator    while (i.hasNext && j.hasNext)      if (!p(i.next(), j.next()))        return false    !i.hasNext && !j.hasNext  }

 

 

 

 

6.7 控制抽象

控制抽象是一类函数:
1、参数是函数。
2、函数参数没有输入值也没有返回值。
 
1)使用示例:
def runInThread(block: () => Unit) {  new Thread {    override def run() { block() }  }.start()} // 传入函数runInThread { () => println("Hi") ; Thread.sleep(10000); println("Bye") }() = > 有些多余,可以使用换名调用来表示,省略()保留=>// 这种叫控制抽象函数 (看上去像是编程语言关键字的函数)def runInThread(block: => Unit) {  new Thread {    override def run() { block }  }.start()} // 优雅的传入runInThread { println("Hi") ; Thread.sleep(1000); println("Bye") } //可以定义类似于 while 的 until 函数def until(condition: => Boolean)(block: => Unit) {  if (!condition) {    block    until(condition)(block)  }} var x = 10 until (x == 0) {
  x -= 1   println(x) }

 

 

笔记:

//6.7 控制抽象def runOnThread(f1:() => Unit): Unit = {  new Thread{    override def run(): Unit = {      f1()    }  }.start()}runOnThread({  () => println("干活!")    Thread.sleep(5000)    println("活干完了!")})//    () => 1; 2; 3 + 1

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/LXL616/p/11122087.html

你可能感兴趣的文章
静态变量数组实现LRU算法
查看>>
中文系统 上传file的input显示英文
查看>>
比callback更简洁的链式执行promise
查看>>
android permission
查看>>
【译】在Asp.Net中操作PDF - iTextSharp - 使用字体
查看>>
.net 文本框只允许输入XX,(正则表达式)
查看>>
Python 第四十五章 MySQL 内容回顾
查看>>
实验2-2
查看>>
MongoDB遇到的疑似数据丢失的问题。不要用InsertMany!
查看>>
android smack MultiUserChat.getHostedRooms( NullPointerException)
查看>>
监控工具之---Prometheus 安装详解(三)
查看>>
不错的MVC文章
查看>>
IOS Google语音识别更新啦!!!
查看>>
[置顶] Linux终端中使用上一命令减少键盘输入
查看>>
BootScrap
查看>>
路冉的JavaScript学习笔记-2015年1月23日
查看>>
Mysql出现(10061)错误提示的暴力解决办法
查看>>
2018-2019-2 网络对抗技术 20165202 Exp3 免杀原理与实践
查看>>
Swift - 异步加载各网站的favicon图标,并在单元格中显示
查看>>
【Python学习笔记】1.基础知识
查看>>