Scala暗示并覆盖问题

时间:2016-11-21 15:58:08

标签: scala implicit method-overriding

这是我的问题:

trait Caller {

    type EntityType
    def parseEntity(entity: String): EntityType
}

trait IntCaller extends Caller {

    implicit def strToInt(s: String) = s.toInt
    override type EntityType = Int
    override def parseEntity(entity: String): EntityType = entity
}

trait DoubleCaller extends Caller {

    implicit def strToDouble(s: String) = s.toDouble
    override type EntityType = Double
    override def parseEntity(entity: String): EntityType = entity
}    

object main {

    def main(args: Array[String]): Unit = {
        val intCaller = new IntCaller{}
        val doubleCaller = new DoubleCaller{}

        println("Result is: " + intCaller.parseEntity("5"))
        println("Result is: " + doubleCaller.parseEntity("5.0"))
    }

}

正如您所看到的,我不断重复以下代码:parseEntity方法。如果我想添加FloatCaller,我将不得不重写parseEntity,即使它的实现方式是相同的。

如何在Caller中编写parseEntity的实现,这样我就不必一次又一次地在子特征中编写相同的代码?

声明: 这是SprayJsonSupport akka.http.scaladsl.marshallers.sprayjsonstd::map< int, std::vector<int> > list2D; 的真正问题的简化。

1 个答案:

答案 0 :(得分:4)

最好使用可以在给定转换函数的情况下构建IntCaller实例的工厂方法。 DoubleCallertoInt之间唯一不同的是toDoubletrait Caller { type EntityType def parseEntity(entity: String): EntityType } object Caller { def apply[A](f: String => A): Caller = new Caller { type EntityType = A def parseEntity(entity: String): EntityType = f(entity) } } scala> val IntCaller = Caller(_.toInt) scala> IntCaller.parseEntity("123") res1: IntCaller.EntityType = 123 scala> val DoubleCaller = Caller(_.toDouble) scala> DoubleCaller.parseEntity("1.23") res2: DoubleCaller.EntityType = 1.23 (当然还有类型)。

parseEntity

如果要继续使用继承,请继续强制子类或特征以parseEntity实现转换。但是,使用隐式转换并不是必需的。出现重复代码的唯一原因是因为隐式转换使trait Caller { type EntityType def parseEntity(entity: String): EntityType } trait IntCaller { type EntityType = Int def parseEntity(entity: String): EntityType = entity.toInt } 对于每个实现看起来都相同,即使它实际上并非如此(因为它需要解析不同的隐式)。

df['c'] = np.minimum(df.a,df.b)