spark快速开发之scala基础之5高阶函数,偏函数,闭包
高阶函数
高阶函数就是将函数作为参数或者返回值的函数。
object function {
def main(args: Array[String]): Unit = {
println(test(f,10))
}
def test(f:Int => String , num : Int) = f(num)
def f(num:Int) : String = {
10 + num + ""
}
}
在spark中,经常将只需要执行一次的函数定义为匿名函数作为参数传递给高阶函数。如map,flatMap。
以map为例,最全面的写法是
object function {
def main(args: Array[String]): Unit = {
val list = List("spark","hadoop","hbase")
list.map(f2:String=>(String,Int)).foreach(println)
}
def f(x:String) : (String,Int) = {
(x,1)
}
}
匿名函数的写法
list.map((x:String) => (x,1)).foreach(println)
利用匿名函数的参数推断,可以进一步简化的写法
list.map((x) => (x,1)).foreach(println)
如果只有一个参数
list.map(x => (x,1)).foreach(println)
可以使用_代替参数
list.map((_,3)).foreach(println)
偏应用函数
偏应用函数指的是如果一个函数有n个参数,为其提供少于n个参数的函数叫做偏应用函数。又叫做部份函数。其实也点类似于方法重载。
def f1(x:Int,y:Int,z:Int) = x+y+z def f2(y:Int,z:Int) = f1(1,y,z)
偏函数
scala里的偏函数也是数学中的一个概念,指定义域X中可能存在某些值在值域Y中没有对应的值,通俗点说就是入参是在指定的范围内,因此它比普通的函数多了个isDefinedAt方法,用于判断参数是否在该函数的接受范围内。不同于普通函数,偏函数是scala.PartialFunction[-A,+B]的对象。

先看一个例子
//这是一个偏函数
val pf: PartialFunction[Int, String] = {
case 1 => "One"
case 2 => "Two"
case 3 => "Three"
} //这不是一个偏函数
val pf2: PartialFunction[Int, String] = {
case 1 => "One"
case 2 => "Two"
case 3 => "Three"
case _ => "else"
} println(pf(1)) //One
println(pf2(4)) //else
println(pf(4)) //异常
偏函数的定义
PartialFunction[Int, String]
Int为输入类型,String为返回值类型。
pf的定义域为所有int,值域为【1,2,3】,除了【1,2,3】以外的参数并没有与之对应的返回值。所以pf是一个偏函数。调用偏函数传入定义域以外的参数就会报错,但是偏函数提供了其它的方法来避免这种情况。
使用isDefinedAt来判断是否可以传入此参数,返回一个布尔值。
println(pf.isDefinedAt(4)) //false
orElse相当于连接。条件是两个偏函数的类型是一样的。
val pf: PartialFunction[Int, String] = {
case 1 => "One"
case 2 => "Two"
case 3 => "Three"
}
val pf2: PartialFunction[Int, String] = {
case 4 => "Four"
case 5 => "Five"
case 6 => "Six"
}
pf orElse pf2相当于
val pf: PartialFunction[Int, String] = {
case 1 => "One"
case 2 => "Two"
case 3 => "Three"
case 4 => "Four"
case 5 => "Five"
case 6 => "Six"
}
andThen
pf andThen pf3
pf3 andThen pf//异常 val pf2: PartialFunction[Int, String] = {
case 1 => "One"
case 2 => "Two"
case 3 => "Three"
case _ => "else"
} val pf3: PartialFunction[String, String] = {
case "One" => "One"
case "Two" => "Two"
case "Three" => "Three"
case "else" => "else"
}
偏函数的意义在于粒度的问题。可以把一个函数细分,然后在不同的功能的时候对这些函数进行排列组合,自由灵活的达到想要的功能。
柯里化
看代码最直观
def add(x:Int,y:Int,z:Int) = x+y+z
def add2(x:Int)(y:Int)(z:Int) = x+y+z
函数add到add2的过程就是柯里化。两个函数参数类型个数和返回值都是一样的。但是过程不一样。
函数add直接相加。
函数add2先演变为
val result = add2(x)
再演变为
val add2(y:Int) = result + y
val result2 = add2(y)
最后是
val add2(z:Int) = result2 + z
val result3 = add2(z)
关于其应用及其意义,参照fold,aggregate。
闭包
闭包函数返回值依赖于函数外部的变量。
val y : Int = 0
def f(x:Int) = x + y
println(f(10))
我们定义了一个形参x,调用的时候传入,另一个函数外部的变量y,是一个自由变量。这样就定义了一个闭包。因为它引用到函数外面定义的变量,定义这个函数的过程是将这个自由变量捕获而构成一个封闭的函数。
spark快速开发之scala基础之5高阶函数,偏函数,闭包的更多相关文章
- spark快速开发之scala基础之1 数据类型与容器
写在前面 面向java开发者.实际上,具有java基础学习scala是很容易.java也可以开发spark,并不比scala开发的spark程序慢.但学习scala可有助于更快更好的理解spark.比 ...
- spark快速开发之scala基础之3类,对象,特征
类 scala的类定义非常灵活 class test4 class test2{} class test3(x:Int) 定义一个带构造函数的类 class Point (x : Int,y : In ...
- spark快速开发之scala基础之2控制流程
判断结构 大体与java相当.scala没有三元表达式. val num = if(1>0) 1 else 0 //相当于匿名函数 println(num) var num2 = 0 if(1& ...
- python 基础 4.3 高阶函数下和匿名函数
一 .匿名函数 顾名思议就是没有名字的函数,那为什么要设立匿名函数,他有什么作用呢?lambda 函数就是一种快速定义单行的最小函数,可以用在任何需要函数的地方. 常规版: def fun(x,y ...
- Scala学习十二——高阶函数
一.本章要点 在Scala中函数是”头等公民“(可以作为参数,返回值,赋值给其他); 可以创建匿名函数,通常还会交给其他函数; 函数参数可以给出需要稍后执行的行为; 许多集合方法都接受函数参数,将函数 ...
- scala学习笔记:高阶函数
scala> def power(y:Double)=(x:Double)=>Math.pow(x,y) warning: there were 1 deprecation warning ...
- python 基础 4.2 高阶函数上
一.高阶函数 把函数当做参数传递的一种函数 1>map()函数 map函数是python内置的一个高阶函数,它接受一个函数f和一个list,并把list元素以此传递给函数f,然后返回一个函数 ...
- Scala集合操作中的几种高阶函数
Scala是函数式编程,这点在集合操作中大量体现.高阶函数,也就是能够接收另外一个函数作为参数的函数. 假如现在有一个需要是将List集合中的每个元素变为原来的两倍,现在来对比Java方式实现和Sca ...
- Scala高阶函数与泛型
1. Scala中的函数 在Scala中,函数是“头等公民”,就和数字一样.可以在变量中存放函数,即:将函数作为变量的值(值函数). 2. scala中的匿名函数,即没有函数名称的函数,匿名函数常作为 ...
随机推荐
- CCF-权限查询-201612-3
这道题,开始只有10分.....原因是将false 写成了 flase 我要吐血而亡....关键是还debug了半天,以为是逻辑错了 不过亮点是代码很简洁,网上140+的代码看着真复杂 核心: 做题之 ...
- python 的 format 函数
python的格式化字符串方法之一------------format 函数 它通过{}和:来代替%. 数字 格式 输出 描述 3.1415926 {:.2f} 3.14 保留小数点后两位 3.141 ...
- 使用FileZilla连接时超时,无法连接到服务器
更改一下加密方式,就是不用TLS,用相对不安全方式的(可选项) 腾讯云就是这样的,
- 创建一个dynamics 365 CRM online plugin (二) - fields检查
Golden Rules 1. Platform only passes Entity attributes to Plugin that has change of data. 2. If the ...
- 东芝 B-EV4 打印机 串口打印命令
最近在做项目时候使用了东芝的B-EV4打印机,在打印Excel时候由于字体太小,导致打印非常模糊.只能通过串口名称发送打印指令进行打印.在做项目的时候查了很多关于B-EV4打印机的资料,和打印命令.资 ...
- SoundManager 2 / API Demo and Code Examples
http://www.schillmania.com/projects/soundmanager2/
- redis 安装配置学习笔记
redis 安装配置学习笔记 //wget http://download.redis.io/releases/redis-2.8.17.tar.gz 下载最新版本 wget http://downl ...
- 如何在同一主机中添加多个homestead并行开发
参考源 https://blog.csdn.net/smm188/article/details/79356150 1,在项目目录 git clone homestead 后(见上面流程中的第四步), ...
- 分布式CAP定理,为什么不能同时满足三个特性?
在弄清楚这个问题之前,我们先了解一下什么是分布式的CAP定理. 根据百度百科的定义,CAP定理又称CAP原则,指的是在一个分布式系统中,Consistency(一致性). Availability(可 ...
- ProxySQL Cluster的搭建
环境: proxysql-1.4.10-1-centos7.x86_64 db210 192.168.99.210 老节点,已经做成mysql配置和读写分离设置db211 192.168.99.211 ...