withSpout在spark中是用来做DAG可视化的,它在代码里的用法如下(以map为例,spark 2.0.0版本)

def map[U: ClassTag](f: T => U): RDD[U] = withScope {
val cleanF = sc.clean(f)
new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.map(cleanF))
}

因为对scala语法比较生疏,初次见面,一脸懵逼,这里的withScope是个什么用法?乍看一下有种java的implements Comparable的感觉。

其实,withScope是一个函数。

map()的函数体其实就是调用了一下withScope,将泛型什么的先去掉,代码简单来看就是下面这个样子。

def map(f): RDD = withScope(func)

因为函数体只有简单的一句,所以省略了大括号 "{ }"。
map函数补上大括号可以是这个样子。

def map[U: ClassTag](f: T => U): RDD[U] = {
withScope {
val cleanF = sc.clean(f)
new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.map(cleanF))
}
}

函数只有单一参数,调用时,有时小括号和花括号是可以互换的  比如

rdd.map(x => x._1) //小括号
rdd.map{x => x._1} //花括号

这里,map()的参数是一个匿名函数,一句简短代码即可搞定。但是,当函数用一句搞不定时,就需要使用"{}"来界定代码块了。其实,于小括号和花括号之间来回切换的例子,在写spark程序时,经常遇到。
比如:

rdd.map(x => x._1).filter {
... //一些用一句代码不易搞定的复杂过滤逻辑
}

回到withScope,它就是一个只有单一参数的函数,而这个单一参数本身也是个函数。

private[spark] def withScope[U](body: => U): U = RDDOperationScope.withScope[U](sc)(body)

withScope的参数名是body,其类型是 => U。这表示body是一个函数,这个函数没有参数(=>左边没东西),而返回类型任意(=>右边是个泛型U)。

withScope的形式跟map类似。

柯里化函数

我们看到上文中的withScope()又调用了RDDOperationScope中定义的withScope,而且调用方式有些奇怪。有两个参数sc和body,而且用了两个括号。
再去看RDDOperationScope中withScope的定义,参数中也用了两个括号。第一个括号定义了sc和allowNesting参数,第二个括号定义了body参数。
这种形式在scala中叫做柯里化(currying)。

rivate[spark] def withScope[T](
sc: SparkContext,
allowNesting: Boolean = false)(body: => T): T = {
...
}

柯里化是将原先一次性接受的参数,改成了链式接受的形式。这里引用《快学scala》中的例子说明。

def mul(x: Int)(y: Int) = x * y //定义柯里化函数
mul(6)(7) //调用柯里化函数

严格来讲,首先调用mul(6),返回的结果是函数(y: Int) => 6 * y (x被替换成了6)。而这个函数又被应用到了7,最终得到42。
柯里化的本质是什么呢?

其实,上面的mul()是如下形式的简写。mul()本质上是定义了一个只有参数x的函数,其返回结果是另一个函数。

def mul(x: Int) = (y: Int) => x * y

最新文章

  1. ngx_http_proxy_module模块.md
  2. Python traceback【转】
  3. lua 和 c/c++ 交互 (持续更新)
  4. robotframework接口测试初探1
  5. Oracle bbed 实用示例-----File Header Reset
  6. 一篇文章教会你,如何做到招聘要求中的“要有扎实的Java基础
  7. IOS-objectForKey与valueForKey在NSDictionary中的差异
  8. MailBee的简单使用
  9. Python之路:Python 基础(一)
  10. docker 报错:x509: certificate has expired or is not yet valid
  11. Java 小记 — Spring Boot 注解
  12. Python学习 Part6:错误和异常
  13. 多线程threading
  14. select2 api参数的文档
  15. mint-ui loadmore使用方法和注意事项
  16. java实现表格tr拖动
  17. Git 创建分支与合并分支
  18. dell T420热插拔安装过程
  19. C# 所生成项目的处理器架构“MSIL”与引用“Oracle.DataAccess, Version=4.112.3.0, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86”的处理器架构“x86”不匹配。这种不匹配可能会导致运行时失败。
  20. java中Filter过滤器处理中文乱码的方法

热门文章

  1. Using gcc stack debug skill
  2. 在sorted range上的操作(includes,set_union,set_intersection,set_difference)
  3. jquery 实现的全选demo
  4. 安装ES
  5. Iris花逻辑回归与实现
  6. spring-IOC容器(二)
  7. [转]跳板机Jumpserve的生产环境配置
  8. ASP.NET中使用JSON方便实现前台与后台的数据交换
  9. Ntfs 下的链接符号创建
  10. git命令的简单使用