2017-05-25 73 views
2

我有一个要求在runTime中拦截dateTime,LocalDate和Option的toString。类型类型的默认隐式对象/定义

@implicitNotFound("No member of type class ReportString in scope for ${T}") 
trait ReportStringTransformer[T] { 
    def toReportString(e: T): String 
} 

object ReportStringTransformer { 
    implicit object ReportStringTransformerDateTime 
    extends ReportStringTransformer[DateTime] { 
     override def toReportString(e: DateTime): String = 
     ISODateTimeFormat.dateTime().print(e) 
    } 

    implicit object ReportStringTransformerDate 
    extends ReportStringTransformer[LocalDate] { 
     override def toReportString(e: LocalDate): String = 
     ISODateTimeFormat.date().print(e) 
    } 

    implicit def ReportStringTransformerOpt[T]: ReportStringTransformer[Option[T]] = 
    new ReportStringTransformer[Option[T]] { 
     override def toReportString(e: Option[T]): String = e match { 
     case Some(obj) => ReportStringTransform.transform(obj) 
     case None => "" 
     } 
    } 
} 

object ReportStringTransform { 
    def transform[T](obj: T)(implicit t: ReportStringTransformer[T]): String = 
    t.toReportString(obj) 
} 

我可以添加一个默认的变压器在这只能 后这些被拾起末的所有类,但没有任何其他清洁的方式呢?

回答

2

您的实现可以如下简化:

@implicitNotFound("No member of type class Show in scope for ${T}") 
case class Show[T](f: T => String) extends AnyVal 

object Show { 
    implicit val showDateTime = Show[DateTime](ISODateTimeFormat.dateTime() print _) 
    implicit val showDate = Show[LocalDate](ISODateTimeFormat.date() print _) 
    implicit def showOpt[T](implicit s: Show[T]) = Show[Option[T]](_.fold("")(s.f)) 
} 

为了有一个后备的任何不是一个DateTime,一个LocalDate或者要么这些的Option,可以将以下特征作为一个paraent object Show

trait LowPriorityShow { 
    implicit def showAnything[T] = Show[T](_.toString) 
} 

object Show extends LowPriorityShow { ... } 
+0

从2.10开始,本地含义和隐含属于同一范围。以上wouldnt工作 – tez

+0

你也使用猫? – tez

+0

在此示例中不使用cat,show是此类型类的标准名称。您关于隐式作用域的声明不正确,请参阅http://eed3si9n.com/revisiting-implicits-without-import-tax。 – OlivierBlanvillain