2017-05-25 54 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