我试图定义一个简单的CRUD系统使用的基本特征。但是,我需要基本特征来支持“copyWithId”def(因为Scala案例类的复制魔法不可用)。到目前为止,我已经找到了最好的办法是:定义一个scala特质def返回一个具体的子类型实例
trait Identifiable[ID, T] {
def id: Option[ID]
def copyWithId(id: Option[ID]): T
}
case class TestNamedIdentity(id: Option[Int], name: String)
extends Identifiable[Int, TestNamedIdentity] {
def copyWithId(id: Option[Int]): TestNamedIdentity = {
copy(id = id)
}
}
这工作,但因为它需要所有的具体实例与ID和自我扩展看起来有点笨重。我想写一些如下:
trait Identifiable[ID] {
this:X =>
def copyWithId(id: Option[ID]): X
def id: Option[ID]
}
使用某种形式的自引用具体类。任何方式使这项工作?
更新:随着使用情况如下
的想法是使用它的代码就像
abstract class SomeClass[A <: IdentifiableEntity[ID], ID] {
def someFunc2: Option[ID]
def someFunc(item: A): A = {
item.copyWithId(someFunc2)
}
}
使用从@jwvh的解决方案需要调用后“asInstanceOf”铸造。哪些用于我的用例,但希望得到更优雅的解决方案。
item.copyWithId(someFunc2).asInstanceOf[A]
第一种形式是唯一一个我知道需要写一个涉及'Identifiable'也返回'T'参数化方法时很好地工作。重写复制方法看起来很笨重,但对于我认为更差的CRUD方法也是如此,所以我已经处理了它。除此之外,我能想到的最好的方法来保存一些样板文件将是一个宏,但它只会节省很多。以抽象的方式处理“copy”是非常棘手的。 –
@MichaelZajac我担心宏将是唯一可行的解决方案,我不愿意为代码库添加这种级别的混淆。我认为jwvh的方法对于api消费者来说至少比我上面的第一种形式更清晰。 – rapidninja