在 Scala 2 中,我在一个简单的 ORM 模型中使用了类型投影,其中包含
IdEntity
和一些存储库。现在我尝试迁移到 Scala 3,但由于缺少 #
的类型投影而卡住了。
简化的代码如下所示:
trait IdEntity:
type ID_Type
val id: ID_Type
trait IdLongEntity extends IdEntity:
override type ID_Type = Long
trait IdStringEntity extends IdEntity:
override type ID_Type = String
trait IdRepository[E <: IdEnity]:
def findById(id: E#ID_Type): Option[E]:
有什么想法可以克服
def findById(id: E#ID_Type)
中缺少的类型投影吗?
我已经尝试过类似的类型匹配
object IdEntity:
type Aux[K] = IdEntity {type ID_Type = K}
type IdType[T <: IdEntity] = T match
case IdEntity.Aux[k] => k
但这不起作用,因为编译认为类型不匹配。
确实,其中一种方法是匹配类型:
trait IdEntity:
type ID_Type
val id: ID_Type
object IdEntity:
type Aux[K] = IdEntity {type ID_Type = K}
trait IdLongEntity extends IdEntity:
override type ID_Type = Long
trait IdStringEntity extends IdEntity:
override type ID_Type = String
type IdType[T <: IdEntity] = T match
case IdEntity.Aux[k] => k
trait IdRepository[E <: IdEntity]:
def findById(id: IdType[E]): Option[E] = ???
这不起作用,因为编译认为类型不匹配
你应该准备复制,我们看看是否可以修复编译。
另一种方式是类型类:
trait IdEntity:
type ID_Type
val id: ID_Type
object IdEntity:
type Aux[K] = IdEntity {type ID_Type = K}
trait IdLongEntity extends IdEntity:
override type ID_Type = Long
trait IdStringEntity extends IdEntity:
override type ID_Type = String
trait IdType[T <: IdEntity]:
type Out
object IdType:
given [k]: IdType[IdEntity.Aux[k]] with
type Out = k
trait IdRepository[E <: IdEntity]:
def findById(using idType: IdType[E])(id: idType.Out): Option[E] = ???
或者您甚至可以使用从
IdEntity
开始的类型类,例如使 IdEntity
成为类型类。