我要求在runTime中拦截to Date of DateTime,LocalDate和Option。
@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)
}
我可以在最后添加Any类的默认变换器 在这些之后被接走,但还有其他更清洁的方法吗?
答案 0 :(得分: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
的内容进行后备,您可以使用以下特征作为{{1}的副本}
object Show
答案 1 :(得分:1)
派对可能迟到了,但你的问题here上的问题是,隐含的解决方案会为你提出的第二种情况选择Some [String]类型。除此之外,OlivierBlanvillain给出的解决方案很棒,它可以解决您的需求。
您可以通过强制转换为Option [String]
来验证这种情况println(MyShow.show(Some("abc"): Option[String])) // this will work as you expected
使用方差/协方差,可以使其按预期工作link。
import org.joda.time.{DateTime, DateTimeZone}
import org.joda.time.format.ISODateTimeFormat
trait Show[-T] {
def show: T => String
}
trait LowPriorityShow {
implicit def showAnything[T] = new Show[T] {
def show: T => String = _.toString
}
}
object Show extends LowPriorityShow {
implicit val showString: Show[String] = new Show[String] {
def show: String => String = identity
}
implicit val showDateTime: Show[DateTime] =
new Show[DateTime] {
def show: DateTime => String =
ISODateTimeFormat.dateTime().withZone(DateTimeZone.forID("America/New_York")).print
}
implicit def showOpt[T : Show]: Show[Option[T]] =
new Show[Option[T]] {
def show: Option[T] => String = _.fold("")(implicitly[Show[T]].show)
}
def show[T : Show](v: T): String = implicitly[Show[T]].show(v)
}
println(Show.show(DateTime.now()))
println(Show.show(Some("abc")))
println(Show.show(12))