我试图使用implicits尝试覆盖我在ADT案例类中的序列化方法,但是我无法理解它应该如何完成
// START OF API//
/**
* Serialize methods defined here
*
*/
object Serializer {
def string(block: (String => String)) = block
def int(block:(Int => String)) = block
def double(block:(Double => String)) = block
}
/**
* These are the DEFAULT serializers
*/
object Implicits {
implicit val string = Serializer.string (s => s)
implicit val int = Serializer.int (i => i.toString)
implicit val double = Serializer.double (d => String.valueOf(d))
}
/**
*
* Our simple ADT defined here
*/
import Implicits._
abstract class Vehicle {
def serialize:String
}
case class Car(s:String) extends Vehicle {
def serialize: String = string(s)
}
case class Truck(i:Int) extends Vehicle {
def serialize: String = int(i)
}
case class RocketShip(d:Double) extends Vehicle {
def serialize: String = double(d)
}
// END OF API
// START OF USER CODE
object UserImplicit {
implicit val string = Serializer.string(s => s.capitalize)
}
object Main extends App{
val v = Car("some car")
println(v.serialize)
import test.UserImplicit._
// This SHOULD print a capatilized version i.e. SOME CAR
println(v.serialize)
}
// END OF USER CODE
基本上我想修补默认的序列化程序方法(object Implicits
中包含的方法),以便API的用户可以实现自己的序列化程序
我尝试了很多种组合(例如在trait
而不是object
中有隐含的内容)但是我实际上没有设法使其正常工作
答案 0 :(得分:3)
我认为你真的想为此使用类型类。很简单,在Scala中,您可以根据需要提供自己的(或“覆盖”)。
trait Serializer[A] extends (A => String)
object Serializer {
def Serializer[A: Serializer] = implicitly[Serializer[A]]
}
trait SerializerInstances {
implicit val StringSerializer = new Serializer[String] {
def apply(s: String) = s
}
implicit val IntSerializer = new Serializer[Int] {
def apply(i: Int) = i.toString
}
implicit val DoubleSerializer = new Serializer[Double] {
def apply(i: Int) = i.toString
}
implicit def TupleSerializer[A: Serializer, B: Serializer] = new Serializer[(A, B)] {
def apply(t: (A, B)) = s"(${Serializer[A](a)}, ${Serializer[B](b)})"
}
}
现在,要使用它们,您只需声明您的代码需要采用具有Serializer上下文绑定的东西:
def somethingThatDoesSerialization[A: Serializer](a: A) = {
val serializedForm: String = Serializer[A](a)
…
}
您现在可以导入/管理适合您需要的任何序列化程序集。
答案 1 :(得分:0)
我实际上设法使用pimp我的库模式来解决它,这是一个工作代码的例子
object Implicits {
def defaults(v:Vehicle):String = {
v match {
case Car(c) => "This is car " + c
case Truck(t) => "This is a truct " + t
case RocketShip(r) => "This is a rocketship " + r
}
}
class VehicleSerializer(v:Vehicle) {
def serialize:String = defaults(v)
}
implicit def vSerialize(v:Vehicle) = new VehicleSerializer(v)
}
/**
* Our simple ADT defined here
*/
abstract class Vehicle {}
case class Car(s: String) extends Vehicle {}
case class Truck(i: Int) extends Vehicle {}
case class RocketShip(d: Double) extends Vehicle {}
// END OF API
// START OF USER CODE
class UserImplicit(v:Vehicle) {
def serialize:String = {
v match {
case Car(c) => "This is a MASSIVE car " + c
case _v => Implicits.defaults(_v)
}
}
}
object Test extends App {
val c = Car("rawr")
// This is the default serializer
{
import Implicits._
println(c.serialize)
}
// This is our overwritten serializer
{
implicit def vSerialize(v:Vehicle) = new UserImplicit(v)
println(c.serialize)
}
}
// END OF USER CODE
打印
This is car rawr
This is a MASSIVE car rawr
按预期