根据设计,我们确信我们有一个 HourlyDateFormat
在这种情况下如何避免调用 asInstanceOf(即如何帮助编译器推断类型)?
sealed trait StorageLayout extends Product with Serializable
case object Hourly extends StorageLayout
case object Daily extends StorageLayout
sealed trait DateFormat[S <: StorageLayout]
sealed abstract class HourlyDateFormat extends DateFormat[Hourly.type] {
def format(localDate: LocalDate): String = ???
def format(localDateTime: LocalDateTime): String = ???
}
sealed abstract class DailyDateFormat extends DateFormat[Daily.type] {
def format(localDate: LocalDate): String = ???
}
class Log[S <: StorageLayout](storageLayout: S, dateFormat: DateFormat[S]) {
def getPath(date: LocalDate): String =
dateFormat match {
case hdf: HourlyDateFormat => hdf.format(date)
case ddf: DailyDateFormat => ddf.format(date)
}
@SuppressWarnings(Array("org.wartremover.warts.AsInstanceOf"))
def getPath(date: LocalDateTime)(implicit ev: S =:= Hourly.type): String = {
assert(ev == ev)
dateFormat.asInstanceOf[HourlyDateFormat].format(date)
}
}
Run Code Online (Sandbox Code Playgroud)
尝试再添加一个隐式参数
def getPath(date: LocalDateTime)(implicit ev: S =:= Hourly.type, ev1: DateFormat[S] =:= HourlyDateFormat): String = {
//assert(ev == ev)
dateFormat.format(date)
}
Run Code Online (Sandbox Code Playgroud)
断言看起来很奇怪:assert(ev == ev)。
要不就
def getPath(date: LocalDateTime)(implicit ev1: DateFormat[S] =:= HourlyDateFormat): String
Run Code Online (Sandbox Code Playgroud)
固定版本(我又添加了一个类型参数,它现在类似于第一个@user的版本)
class Log[S <: StorageLayout, D <: DateFormat[S]](storageLayout: S, dateFormat: D) {
def getPath(date: LocalDate): String =
dateFormat match {
case hdf: HourlyDateFormat => hdf.format(date)
case ddf: DailyDateFormat => ddf.format(date)
}
def getPath(date: LocalDateTime)(implicit
ev: S =:= Hourly.type,
ev1: D <:< HourlyDateFormat,
): String = {
dateFormat.format(date)
}
}
val log = new Log(Hourly, new HourlyDateFormat(){})
print(log.getPath(LocalDateTime.now()))
Run Code Online (Sandbox Code Playgroud)
通常这样的事情有点类型优雅,所以我会这样做:
trait DailyFormatter[S] {
def formatDate(localDate: LocalDate): String
}
trait HourlyFormatter[S] {
def formatDateTime(localDateTime: LocalDateTime): String
}
implicit val dailyFormats: DailyFormatter[Daily]
implicit val hourFormats: DailyFormatter[Hourly] with HourlyFormatter[Hourly]
class Log[S <: StorageLayout](storageLayout: S, dateFormat: DateFormat[S]) {
def getPath(date: LocalDate)(implicit formater: DailyFormatter[S]): String =
formater.formatDate(date)
def getPath(date: LocalDateTime)(implicit formater: HourlyFormatter[S]): String =
formater.formatDateTime(date)
}
Run Code Online (Sandbox Code Playgroud)
它的优点是您不必知道类型的存在HourlyDateFormat并DailyDateFormat使其工作。
| 归档时间: |
|
| 查看次数: |
130 次 |
| 最近记录: |