首页 > 其他分享 >Scala高阶函数

Scala高阶函数

时间:2022-11-11 16:31:19浏览次数:58  
标签:函数 Scala Int minusxy 柯里化 println 高阶 def


1  作为参数的函数

函数作为一个变量传入到了另一个函数中,那么该作为参数的函数的类型是:function1,即:(参数类型) => 返回类型

def plus(x: Int) = 3 + x
val result1 = Array(1, 2, 3, 4).map(plus(_))
println(result1.mkString(","))

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

2  匿名函数

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

val triple = (x: Double) => 3 * x
println(triple(3))

3  高阶函数

能够接受函数作为参数的函数,叫做高阶函数。

1)  高阶函数的使用

def highOrderFunction1(f: Double => Double) = f(10)
def minus7(x: Double) = x - 7
val result2 = highOrderFunction1(minus7)
println(result2)

2)  高阶函数同样可以返回函数类型

def minusxy(x: Int) = (y: Int) => x - y
val result3 = minusxy(3)(5)
println(result3)

4  参数(类型)推断

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

5  闭包

闭包就是一个函数把外部的那些不属于自己的对象也包含(闭合)进来。

def minusxy(x: Int) = (y: Int) => x - y

这就是一个闭包:

1) 匿名函数(y: Int) => x -y嵌套在minusxy函数中。

2) 匿名函数(y: Int) => x -y使用了该匿名函数之外的变量x

3) 函数minusxy返回了引用了局部变量的匿名函数

再举一例:

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

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

6  柯里化

函数编程中,接受多个参数的函数都可以转化为接受单个参数的函数,这个转化过程就叫柯里化,柯里化就是证明了函数只需要一个参数而已。其实我们刚才的学习过程中,已经涉及到了柯里化操作,所以这也印证了,柯里化就是以函数为主体这种思想发展的必然产生的结果。

1)  柯里化示例

def mul(x: Int, y: Int) = x * y
println(mul(10, 10))

def mulCurry(x: Int) = (y: Int) => x * y
println(mulCurry(10)(9))

def mulCurry2(x: Int)(y:Int) = x * y
println(mulCurry2(10)(8))

2)  柯里化的应用

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

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

2、比较是否相等

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

val a = Array("Hello", "World")
val b = Array("hello", "world")
println(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
}

尖叫提示:不要设立柯里化存在的意义这样的命题,柯里化,是面向函数思想的必然产生结果。

7  控制抽象

控制抽象是一类函数:

1、参数是函数。

2、函数参数没有输入值也没有返回值。

1)  使用示例

def runInThread(f1: () => Unit): Unit = {
new Thread {
override def run(): Unit = {
f1()
}
}.start()
}

runInThread {
() => println("干活咯!")
Thread.sleep(5000)
println("干完咯!")
}

是不是很爽?是不是有点类似线程池的感觉,同一个线程,可以动态的向里面塞不同的任务去执行。

可以再简化一下,省略(),看下如下形式:

def runInThread(f1: => Unit): Unit = {
new Thread {
override def run(): Unit = {
f1
}
}.start()
}

runInThread {
println("干活咯!")
Thread.sleep(5000)
println("干完咯!")
}

2)  进阶用法:实现类似while的until函数

def until(condition: => Boolean)(block: => Unit) {
if (!condition) {
block
until(condition)(block)
}
}

var x = 10
until(x == 0) {
x -= 1
println(x)
}

标签:函数,Scala,Int,minusxy,柯里化,println,高阶,def
From: https://blog.51cto.com/u_12654321/5845157

相关文章

  • Scala注解
    注解就是标签。标签是用来标记某些代码需要特殊处理的。处理的手段可以在代码运行时操作,也可以在编译期操作。1 什么可以被注解1) 可以为类,方法,字段局部变量,参数,表达式,......
  • C温故补缺(五):main函数的参数
    main()的参数main()函数的参数,用于在外部执行时传入参数,类似windows的bat脚本或linux的sh脚本.在bat脚本中传入参数,用%接收.sh脚本的参数用$接收.c语言编译成可执行文......
  • [欧拉函数] P2158 [SDOI2008] 仪仗队
    题目描述作为体育委员,C君负责这次运动会仪仗队的训练。仪仗队是由学生组成的N\timesNN×N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所......
  • 【Java】 java -jar 命令 传递系统参数 与 main函数参数 顺序
    packagecom.liyao.runner;/***用法:java[-options]class[args...]*(执行类)*或java[-options]-jarjarfile[args...]*(执行ja......
  • JAVA四大核心函数式接口
    Consumer接口1.接口说明Consumer接口是消费性接口,无返回值。Java8中对Consumer的定义如下所示。@FunctionalInterfacepublicinterfaceConsumer<T>{voidaccep......
  • Python函数与类
    某农带专业Python实验二公式计算题目描述:编写三个函数fz(n),fm(n),sum_(n)分别计算下列公式的分子和,分母积以及公式总和值。\[s=1+\frac{1+2}{1\times2}+\frac{1+......
  • C语言 函数03 函数的调用
    传值调用函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。传址调用传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。这种传参方......
  • pytest--测试函数
    参考链接https://docs.python.org/zh-cn/3/reference/simple_stmts.html?highlight=assert#grammar-token-assert_stmt断言assert在pytest中,assert是编写测试的最基......
  • Mysql数据库函数-单行函数
    一.单行函数:可以理解为向函数传入一个参数,返回一个值。单行函数是指对每一题记录输入值进行计算,并得到相应的计算结果,然后返回给用户,也就是说,每条记录作为一个输入参数,经......
  • thinkPHP查询数据库常用函数
      1.find()  查询一条数据2.field()  查询的字段如field('id,name,age')3.select()  查询多条数据4.setField()  修改一个字段或多个字段值  如se......