函数中需要Scala隐式类

  • 本文关键字:Scala 函数 scala implicit
  • 更新时间 :
  • 英文 :


我的目标是为各种类型(时间戳、日期等(配备它们默认情况下可能没有的良好属性(排序、-等(

trait NiceProperties[T] {
def -(t: T): Double
def +(d: Double): T
...
}
implicit class BetterTimestamp(val t: Timestamp) extends NiceProperties[Timestamp] {
override def -(Timestamp): ...
}

这一切都很好,直到我需要将其传递到假设NiceProperties:的函数中

def myUtil[T](t: NiceProperties[T]): T = {
(t + 1.0) + 1.0
}

这现在失败了,因为函数缺少类T可以隐式上转换为NiceProperties[T]的隐式证据,所以它不能将(t + 1.0): T添加到double中。

有没有一种方法可以将隐式类的证据传递到函数中?或者,有更好的模式吗?

您可以通过将NiceProperties[T]变成一个知道如何添加、求和。。。T:类型的两个值

trait NiceProperties[T] {
def subtract(a: T, b: T): Double
def add(a: T, d: Double): T
}

现在,您可以为时间戳、日期等创建隐式NiceProperties对象或val。。。

object BetterTimestamp extends NiceProperties[Timestamp] {
def subtract(a: Timestamp, b: Timestamp): Double = ???
def add(a: Timestamp, d: Double): Timestamp = ???
}

在您的示例方法中,您将请求一个隐式NiceProperties[T],它为您的执行操作。

def myUtil[T](t: T)(implicit prop: NiceProperties[T]): T = {
prop.add(prop.add(t, 1.0), 1.0)
}

由于这很难看,您可以使用隐式类添加+-。。。运算符到隐式NiceProperties[T]可用的任何类:

implicit class NicePropertiesOps[T](t: T)(implicit prop: NiceProperties[T]) {
def +(d: Double): T = prop.add(t, d)
def -(b: T): Double = prop.subtract(t, b)
}

现在,您上面的例子应该和您描述的一样工作。

def myUtil[T : NiceProperties](t: T): T = {
(t + 1.0) + 1.0
}

https://scastie.scala-lang.org/0D1Y9sE5S5mrzm9coZPMWw

@Aki的回答完全正确。这里只是将转换纳入范围的另一种方法。这种方式用于Numeric类型类。

class Timestamp
trait NiceProperties[T] {
def subtract(a: T, b: T): Double
def add(a: T, d: Double): T
implicit class Ops(t:T) {
def +(d: Double): T = add(t, d)
def -(b: T): Double = subtract(t, b)
}
}
implicit object BetterTimestamp extends NiceProperties[Timestamp] {
def subtract(a: Timestamp, b: Timestamp): Double = ???
def add(a: Timestamp, d: Double): Timestamp = ???
}
def myUtil[T](t: T)(implicit prop: NiceProperties[T]): T = {
import prop._
(t + 1.0) + 1.0
}

还有一个有趣的方法。以下是避免导入的方法:

trait NiceProperties[T] extends (T => Ops[T]) {
def subtract(a: T, b: T): Double
def add(a: T, d: Double): T
implicit val v = this
def apply(t:T) = new Ops(t)
}
class Ops[T](t:T)(implicit prop: NiceProperties[T]) {
def +(d: Double): T = prop.add(t, d)
def -(b: T): Double = prop.subtract(t, b)
}
implicit object BetterTimestamp extends NiceProperties[Timestamp] {
def subtract(a: Timestamp, b: Timestamp): Double = ???
def add(a: Timestamp, d: Double): Timestamp = ???
}
def myUtil[T:NiceProperties](t: T): T = {
(t + 1.0) + 1.0
}

现有的答案很好,但是,在无法修改特征的情况下,可以要求隐式转换作为参数:

def myUtil[T](t: T)(implicit conv: T => NiceProperties[T]) = t + 1.0 + 1.0

如果你经常这样做,你可以添加一个抽象类型,这样你就可以使用上下文绑定:

type HasNiceProperties[T] = T => NiceProperties[T]
def myUtil[T : HasNiceProperties](t: T) = t + 1.0 + 1.0

相关内容

  • 没有找到相关文章

最新更新