如何克服Scala 3缺失类型投影?

问题描述 投票:0回答:1

在 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

但这不起作用,因为编译认为类型不匹配。

scala generics scala-3
1个回答
0
投票

确实,其中一种方法是匹配类型:

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
成为类型类。


在Scala 3中,如何替换已被删除的通用类型投影?

Dotty 提供什么来替代类型投影?

© www.soinside.com 2019 - 2024. All rights reserved.