zoukankan      html  css  js  c++  java
  • scala语法在spark withScope上的应用

    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
  • 相关阅读:
    hdu 1171 Big Event in HDU (01背包)
    Codeforces 86C Genetic engineering (AC自己主动机+dp)
    ANDROID L——Material Design具体解释(动画篇)
    三层架构理论篇
    Linux下的tree命令 --Linux下文件夹树查看
    排序之冒泡排序、插入排序及希尔排序
    TRIZ系列-创新原理-9~11-预先反作用原理、预处理原理、预先防范原理
    Linux 获得机器的IP和网卡信息
    Hackerrank
    Android编程之Fragment使用动画造成Unknown animation name: objectAnimator异常
  • 原文地址:https://www.cnblogs.com/lenmom/p/10375119.html
Copyright © 2011-2022 走看看