Scala 选择与未来
我正在用惊人的抽象量构建ubercool应用程序。 现在,我将设计一个基于工程的EntityGetService 我首先想要的是很多抽象类型,比如:Scala 选择与未来,scala,scala-option,Scala,Scala Option,我正在用惊人的抽象量构建ubercool应用程序。 现在,我将设计一个基于工程的EntityGetService 我首先想要的是很多抽象类型,比如: trait EntityGetService[ID, ENTITY, CONTAINER] { def get(id: ID): CONTAINER } trait EntityGetService[ID, ENTITY, CONTAINER <: Wrapper[ENTITY]] { def get(id: ID): CONT
trait EntityGetService[ID, ENTITY, CONTAINER] {
def get(id: ID): CONTAINER
}
trait EntityGetService[ID, ENTITY, CONTAINER <: Wrapper[ENTITY]] {
def get(id: ID): CONTAINER
}
trait EntityGetService[ID, ENTITY] extends AbstractService {
def get( id: ID ): Result[ENTITY] = result {
???
}
// add all the other method implementations here, taking care to
// wrap the method bodies inside "result"
}
// Now specializing EntityGetService as a sync or async service is just a matter
// of mixing SyncService or AsyncService:
class EntitySyncGetService[Long, Entity] extends EntityGetService[Long, Entity] with SyncService
class EntityAsyncGetService[Long, Entity]( implicit val execContext: ExecutionContext ) extends EntityGetService[Long, Entity] with AsyncService
这里的容器是包含(或不包含)请求的实体的类型。与期权[实体]非常相似。但我想要的第二件事是,这个容器也可以是未来的[实体]
所以我真的想这样写:
trait EntityGetService[ID, ENTITY, CONTAINER] {
def get(id: ID): CONTAINER
}
trait EntityGetService[ID, ENTITY, CONTAINER <: Wrapper[ENTITY]] {
def get(id: ID): CONTAINER
}
trait EntityGetService[ID, ENTITY] extends AbstractService {
def get( id: ID ): Result[ENTITY] = result {
???
}
// add all the other method implementations here, taking care to
// wrap the method bodies inside "result"
}
// Now specializing EntityGetService as a sync or async service is just a matter
// of mixing SyncService or AsyncService:
class EntitySyncGetService[Long, Entity] extends EntityGetService[Long, Entity] with SyncService
class EntityAsyncGetService[Long, Entity]( implicit val execContext: ExecutionContext ) extends EntityGetService[Long, Entity] with AsyncService
有没有办法做到这一点而不重新扩展或混合一些东西的选择和未来
看起来Option和Future有一些共同点(它们都是容器)。这和单子有关吗
或者这仅仅是我失眠的产物?不评论这一切的合理性,你可以使用高阶类型:
trait WrappedGetService[ID, ENTITY, WRAPPER[_]] {
def get(id: ID) : WRAPPER[ENTITY]
}
然后您可以声明一个WrappedGetService[Long,Entity,Option]
更新:一些参考资料
该特性被称为高阶类型(也可能是高阶类型)或类型构造函数
- 在中,它应该主要出现在第节中 4.4,类型参数,但不会有太多,它的工作原理与其他类型参数非常相似
- 该功能最初是在论文中提出的。论文可能不会完全按照 语言,但应该非常接近。另一方面,藏书馆走了另一条路,你可以从中看出原因
- 你可以去图书馆看看(不适合胆小的人)。如果你走那条路,你可能也想看看哈斯克尔
- 您可以通过一点我称之为“手动AOP”的方法来实现这一点
首先定义一些基本特征,以捕获将结果包装在
选项
、未来
或任何其他容器中的概念,以及实际包装的方法:
import concurrent._
trait AbstractService {
type Result[T]
protected def result[T]( code: => T ) : Result[T]
}
然后针对未来
和选项
案例专门化此基本特征:
trait SyncService extends AbstractService {
type Result[T] = Option[T]
// Returns the original result wrapped in Some,
// or None if it was null or an exception occured
protected def result[T]( code: => T ) : Option[T] = {
try {
Option( code )
} catch{ case ex: Throwable =>
ex.printStackTrace()
None
}
}
}
trait AsyncService extends AbstractService {
type Result[T] = Future[T]
protected val execContext: ExecutionContext
protected def result[T]( code: => T ) : Future[T] = {
future( code )( execContext )
}
}
现在您可以开始了,可以这样定义EntityGetService特性:
trait EntityGetService[ID, ENTITY, CONTAINER] {
def get(id: ID): CONTAINER
}
trait EntityGetService[ID, ENTITY, CONTAINER <: Wrapper[ENTITY]] {
def get(id: ID): CONTAINER
}
trait EntityGetService[ID, ENTITY] extends AbstractService {
def get( id: ID ): Result[ENTITY] = result {
???
}
// add all the other method implementations here, taking care to
// wrap the method bodies inside "result"
}
// Now specializing EntityGetService as a sync or async service is just a matter
// of mixing SyncService or AsyncService:
class EntitySyncGetService[Long, Entity] extends EntityGetService[Long, Entity] with SyncService
class EntityAsyncGetService[Long, Entity]( implicit val execContext: ExecutionContext ) extends EntityGetService[Long, Entity] with AsyncService
看起来这就是我要找的。你能指出一些资源来阅读这个功能吗?快速谷歌搜索没有任何用处。