F-bounded多态中子类型的Scala重写类型参数
我正在尝试创建一个特性实体,它强制其子类型有2种状态:瞬态和持久
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:playspacemyblogappmodelspostPost.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] { ^ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- datetime – 将unix秒(毫秒)转换为POSIXct/POSIXlt
- vim – 可以使ctags遵循#include指令吗?
- BootStrap学习9---表格
- AngularJS Error: [ng:areq] loginController is not a fun
- 开放才能进步!Angular和Wijmo一起走过的日子
- vim – UltiSnips没有正确触发
- Bash =?在cmd提示符OS X处丢失BASH_REMATCH内容
- angular – tslint error阴影名称:’Observable’
- 为什么我不能从Scala访问实现Java接口的类中声明的变量?
- 是否有用于为Gnome 3设置用户个人资料图标/平铺图片的API?