我試圖定義一個簡單的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