对同一类型使用不同的隐式值

时间:2017-09-27 20:11:26

标签: scala apache-spark

我需要使用Ordering这样调用一个带有隐式implicitly参数的库的排序方法:

class OrderedRDDFunctions[K : Ordering : ClassTag,
                          V: ClassTag] (self: RDD[P]) {

  private val ordering = implicitly[Ordering[K]]

  def sort() = {
    // uses ordering value
  }
}

现在,我需要在一个循环中调用此函数两次,使用相同类型的不同Ordering,如下所示。

var A: RDD[(Int, Int, Int)] = ...
var C: RDD[(Int, Int, Int)] = ...

while(...) {

    implicit val ijOrdering:Ordering[(Int, Int, Int)] = new Ordering[(Int, Int, Int)] {
      override def compare(a: (Int, Int, Int), b: (Int, Int, Int)) = {
        val c = a._1.compare(b._1)
        if(c != 0) c
        else a._2.compare(b._2)
      }
    }
    A.sort() // should use ijOrdering above

    implicit val kjOrdering:Ordering[(Int, Int, Int)] = new Ordering[(Int, Int, Int)] {
      override def compare(a: (Int, Int, Int), b: (Int, Int, Int)) = {
        val c = a._3.compare(b._3)
        if(c != 0) c
        else a._2.compare(b._2)
      }
    }
    C.sort() // should use kjOrdering above

}

sort()方法中有两个不同的隐式Ordering实例。但这给了我一个编译错误。如何在此设置中声明不同的隐式排序?请注意,我无法更改库方法。

1 个答案:

答案 0 :(得分:3)

您可以使用块来限制implicits的范围。一个简单的例子:

object Blocks extends App {
  def meth()(implicit e: Int) = e * 2

  locally {
    implicit val k = 21
    println(meth()) // finds k and prints 42
  }

  locally {
    implicit val j = 11
    println(meth()) // finds j and prints 22
  }
}

如果块之外存在冲突的隐含,则此操作无效。

请注意,locally { ..stmts.. }通常相当于{ ..stmts.. },因此我更喜欢它以便于阅读。您可以详细了解here

的内容