trait EntityState trait Transient extends EntityState trait Persistent extends EntityState trait Entity[State <: EntityState]
例如,一个子类,类Post [State< ;:EntityState]扩展Entity [State],可以实例化为新Post [Persistent]或新Post [Transient].
trait Entity[State <: EntityState] { def id(implicit ev: State <:< Persistent): Long def persist(implicit ev: State <:< Transient): Entity[Persistent] }
为了解释,对于任何扩展Entity的类,只有当类具有Persistent状态时才能调用方法id(即它已保存到数据库并且已经分配了自动生成的id).
另一方面,只有当类是Transient(尚未保存到数据库)时,才能调用方法persist.方法持久化意味着将调用者类的实例保存到数据库并返回该类的持久版本.
现在,问题是我希望persist的返回类型是调用者类的返回类型.例如,如果我在类Post [Transient]的实例上调用persist,它应该返回Post [Persistent]而不是Entity [Persistent].
我四处搜索,发现了一个名为F-Bounded Polymorphism的东西.我正在尝试很多方法来调整它以解决我的问题,但仍然无效.这是我做的:
第一次尝试:
trait Entity[State <: EntityState,Self[_] <: Entity[State,Self]] { def id(implicit ev: State <:< Persistent): Long def persist(implicit ev: State <:< Transient): Self[Persistent] }
和
class Post[State <: EntityState] extends Entity[State,({type λ[B] == Post[State]})#λ] { def persist(implicit ev: <:<[State,Transient]): Post[State] = { ??? } }
在上面的Post类中,我使用Eclipse的自动完成来生成方法persist的实现,并发现它的返回类型仍然不正确.
第二次尝试:
class Post[State <: EntityState] extends Entity[State,Post] { def persist(implicit ev: <:<[State,Transient]): Post[Persistent] = { ??? } }
[error] D:\playspace\myblog\app\models\post\Post.scala:14: kinds of the type arguments (State,models.post.Post) do not conform to the expected kinds of the type parameters (type State,type Self) in trait Entity. [error] models.post.Post's type parameters do not match type Self's expected parameters: [error] type State's bounds <: common.models.EntityState are stricter than type _'s declared bounds >: nothing <: Any [error] trait Post[State <: EntityState] extends Entity[State,Post] {
解决方法
trait Entity[State <: EntityState,Self[S<:EntityState] <: Entity[S,Self]] { _: Self[State] => def id(implicit ev: State <:< Persistent): Long def persist(implicit ev: State <:< Transient): Self[Persistent] } abstract class Post[State <: EntityState] extends Entity[State,Post] { def persist(implicit ev: <:<[State,Transient]): Post[Persistent] = { ??? } }
更新:_:自[状态] => part是一个自我类型的注释.它表示混合Entity特征的任何类都必须扩展Self [State](不这样做会导致编译时错误).如果我们删除这个自我类型的注释,我们可能会定义这样的东西,编译器不会眨眼:
abstract class User[State <: EntityState] extends Entity[State,Transient]): Post[Persistent] = { ??? } }
注意User类如何在Self类型参数设置为Post(而不是User)的情况下扩展Entity.就编译器而言,这是有效的,但肯定不是你想到的.
使用自我类型注释,上面不会编译:
<console>:12: error: illegal inheritance; self-type User[State] does not conform to Entity[State,Post]'s selftype Post[State] abstract class User[State <: EntityState] extends Entity[State,Post] { ^
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。