我想实现通用和类型安全的域存储库。说我有
trait Repo[Value] {
def put(value: Value): Unit
}
case class IntRepo extends Repo[Int] {
override def put(value: Int): Unit = ???
}
case class StringRepo extends Repo[String] {
override def put(value: String): Unit = ???
}
case class DomainRepo(intRepo: IntRepo, stringRepo: StringRepo) {
def putAll[?](values: ?*): Unit // what type should be here?
}
结果我想要以下api:
domainRepo.putAll(1, 2, 3, "foo", "bar") //Should work
domainRepo.putAll(1, 2, true, "foo") // should not compile because of boolean value
问题是如何实现这一目标?
所以,我只看到一种使其类型安全的方法。这是对任何类型进行模式匹配,例如
def putAll(values: Seq[Any]) => Unit = values.foreach {
case str: String => stringRepo.put(str)
case int: Int => intRepo.put(int)
case _ => throw RuntimeException // Ha-Ha
}
但是如果我在这里有 10000 种类型呢?那将是一团糟!
我现在还不清楚的另一种方法是使用 dotty type | (或)如下:
type T = Int | String | 10000 other types // wouldn't be a mess?
def putAll(t: T*)(implicit r1: Repo[Int], r2: Repo[String] ...) {
val myTargetRepo = implicitly[Repo[T]] // would not work
}
所以你怎么看?有可能吗?
我见过的最简单的方法是
Map[Class[_], Repo[_]]
但这种方式允许做很多错误