如何在scala中为不同类型的参数组合相同的函数

时间:2016-08-25 18:48:15

标签: scala

例如,我对lessThanJsNumber有两个完全相同的JsString函数。

def ltNum(left: JsNumber, right: JsNumber, order: SortOrder.Value): Boolean = {
  if (left.value < right.value) {
    order == SortOrder.ASC
  } else {
    order == SortOrder.DSC
  }
}

def ltStr(left: JsString, right: JsString, order: SortOrder.Value): Boolean = {
  if (left.value < right.value) {
    order == SortOrder.ASC
  } else {
    order == SortOrder.DSC
  }
}

这两个函数完全相同,但输入参数类型。 JsNumberJsString来自play-json扩展的库JsValue。但是,value<不是超级特征的一部分。将这些与一个通用功能相结合的任何好主意?

2 个答案:

答案 0 :(得分:5)

您需要提供一些证明两种类型都支持订购的证明。您可以使用Ordering类型类:

执行此操作
// you'll have to figure out a good place to put these
// they'll need to be in scope whenever you *call* the `lt` method
implicit val jsNumberOrdering: Ordering[JsNumber] = Ordering.by(_.value)
implicit val jsStringOrdering: Ordering[JsString] = Ordering.by(_.value)

def lt [A <: JsValue : Ordering] (left: A, right: A, order: SortOrder.Value): Boolean = {
  import Ordering.Implicits._ // will give you the `<` method
  if (left < right) {
    order == SortOrder.ASC
  } else {
    order == SortOrder.DSC
  }
}

答案 1 :(得分:0)

这是泛型的用武之地。你应该能够定义像

这样的东西
def lt[T](left: T, right: T, order: SortOrder.Value): Boolean

在您的情况下,您可能还需要添加绑定 - 如果需要 -

def lt[T <: JsValue](left: T, right: T, order: SortOrder.Value): Boolean

http://docs.scala-lang.org/tutorials/tour/upper-type-bounds.html