scala – 特征上可变数量的类型

我正在创建一个简单的缓存特征(轻松缓存我的函数):

trait Cache[A,B] {
  def _calc(v:A):B
  private var cache = Map[A,B]()
  def calc(v:A):B = {
    cache.get(v) match {
      case Some(x) => x
      case None => 
        val x = _calc(v)
        cache += (v -> x)
        x
    }
  }
}

用法

object Sol extends Cache[Int,Int] {
  def _calc(v:Int):Int = { /* do something here */ }
}
Sol.calc(5)

它工作正常,但问题出现在我需要缓存具有更多参数函数时 – 所以我需要开发特征Cache2,Cache3,来自第一个特征的所有复制粘贴代码.

可能的解决方法是将具有多个参数的函数转换为接受元组函数,但这似乎不正确.

有没有办法更普遍地做到并避免DRY principle违规?

解决方法

您至少可以自动函数进行元组处理,以便您可以定义接受常用参数列表的实际函数(例如add):

object Add extends Cache[(Int,Int),Int]{
    def add (a:Int,b:Int):Int = a+b
    def _calc(t:(Int,Int)) = add _ tupled t
}

通过Add.calc调用它(3,5)

编辑:或者使用这种方式实现Cache2 … CacheN而不重复整个Cache代码.

trait Cache2[A,B,C] extends Cache [(A,B),C] {
    def _calc2(a: A,b: B):C
    def _calc(t:(A,B)) = _calc2 _ tupled t
}

然后再次

object Add2 extends Cache2[Int,Int,Int] {
    def _calc2(a:Int,b:Int) = a+b
}

和Add2.calc(3,5)

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...