这是我的问题:
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.sprayjson
中std::map< int, std::vector<int> > list2D;
的真正问题的简化。
答案 0 :(得分:4)
最好使用可以在给定转换函数的情况下构建IntCaller
实例的工厂方法。 DoubleCaller
和toInt
之间唯一不同的是toDouble
和trait 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)