作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想实现通用且类型安全的域存储库。说我有
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[_]]
但是这种方式可能会犯很多错误
最佳答案
您似乎正在寻找类型类
trait Repo[Value] {
def put(value: Value): Unit
}
implicit val intRepo: Repo[Int] = new Repo[Int] {
override def put(value: Int): Unit = ???
}
implicit val stringRepo: Repo[String] = new Repo[String] {
override def put(value: String): Unit = ???
}
case object DomainRepo {
def putAll[Value](value: Value)(implicit repo: Repo[Value]): Unit = repo.put(value)
}
如果您希望 domainRepo.putAll(1, 2, 3, "foo", "bar")
编译并 domainRepo.putAll(1, 2, true, "foo")
无法编译,可以尝试使用异构集合(HList
)。
import shapeless.{HList, HNil, ::, Poly1}
import shapeless.ops.hlist.Mapper
trait Repo[Value] {
def put(value: Value): Unit
}
implicit val intRepo: Repo[Int] = new Repo[Int] {
override def put(value: Int): Unit = ???
}
implicit val stringRepo: Repo[String] = new Repo[String] {
override def put(value: String): Unit = ???
}
case object DomainRepo {
def put[Value](value: Value)(implicit repo: Repo[Value]): Unit = repo.put(value)
object putPoly extends Poly1 {
implicit def cse[Value: Repo]: Case.Aux[Value, Unit] = at(put(_))
}
def putAll[Values <: HList](values: Values)(implicit
mapper: Mapper[putPoly.type, Values]): Unit = mapper(values)
}
DomainRepo.putAll(1 :: 2 :: 3 :: "foo" :: "bar" :: HNil)
// DomainRepo.putAll(1 :: 2 :: true :: "foo" :: HNil) // doesn't compile
关于scala - 如何在scala中实现类型安全域存储库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55942894/
这就是问题: 我有一个自定义安全域,可以对 Activity 目录中的用户进行身份验证,但从文件中获取角色(将来从数据库中获取) 每个项目的一切都像一个魅力,但是 session 不会在多个项目之间共
我是一名优秀的程序员,十分优秀!