如何解决 Scala 中 MongoRecord 的不变性

发布于 2024-12-09 22:52:21 字数 500 浏览 0 评论 0原文

假设我有一个类定义如下:

class A extends MongoRecord[A]{

}

现在我需要创建一个新类 B,它是 A 的子类:

class B extends A{

}

Object B extends B with MongoMetaRecord[B]

编译器会给出如下错误: 类型参数 [B] 不符合特征 MongoMetaRecord 的类型参数边界 [BaseRecord <: net.liftweb.mongodb.record.MongoRecord[BaseRecord]]
[error] object B extends B with MongoMetaRecord[B]

看起来B类继承了MongoRecord[A],但是由于MongoRecord的不变性,MongoRecord[B]无法替代MongoRecord[A]。因此B类不符合类型约束。知道如何解决这个问题吗?多谢。

Say I have a class defined as follows:

class A extends MongoRecord[A]{

}

Now I need to create a new class B, that is a subclass of A:

class B extends A{

}

Object B extends B with MongoMetaRecord[B]

The compiler would give an error like:
type arguments [B] do not conform to trait MongoMetaRecord's type parameter bounds [BaseRecord <: net.liftweb.mongodb.record.MongoRecord[BaseRecord]]
[error] object B extends B with MongoMetaRecord[B]

It seems that the class B inherits MongoRecord[A], but because of the invariance of MongoRecord, MongoRecord[B] cannot substitute MongoRecord[A]. And therefore class B does not conform to the type constraint. Any idea how to get around this problem? Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

铃予 2024-12-16 22:52:21

你将无法绕过不变性,但不是让 B 成为 A 的子类,也许创建一个 Alike 特征。您可以将 A 转变为特征并创建 ARecord。

trait ALike {
  // all the common stuff
}
class A extends ALike with MongoRecord[A] {
}
class B extends ALike with MongoRecord[B] {
}

You will not be able to get around the invariance but instead of having B a subclass A perhaps make an ALike trait instead. You could turn A into a trait and create an ARecord.

trait ALike {
  // all the common stuff
}
class A extends ALike with MongoRecord[A] {
}
class B extends ALike with MongoRecord[B] {
}
洋洋洒洒 2024-12-16 22:52:21

实际上,代码可能无法编译,因为编译器会抱怨方法“meta”和“id”需要使用正确的类型来实现,但解决方案的想法是正确的。
类 A 用 MongoRecord[A] 和 MongoId[A] 扩展 Alike { def meta = A }

类 B 用 MongoRecord[B] 和 MongoId[B] 扩展 Alike { def meta = B }

对象 A 使用 MongoMetaRecord[A] 扩展 A

对象 B 使用 MongoMetaRecord[B] 扩展 B

Actually the code won't probably compile because the compiler will complain that method "meta" and "id" needs to be implemented with the proper types but the idea of the solution is in the right direction.
class A extends ALike with MongoRecord[A] with MongoId[A] { def meta = A }

class B extends ALike with MongoRecord[B] with MongoId[B] { def meta = B }

object A extends A with MongoMetaRecord[A]

object B extends B with MongoMetaRecord[B]

执笔绘流年 2024-12-16 22:52:21

这是一个迟到的回复,但也许其他人会发现它有用;)

abstract class A[U <: A[U]] extends MongoRecord[U] with ... with ObjectIdPk[U] with ... {
  self: U =>

  object text extends StringField(this, 255)

  ... // other fields
}

class B extends A[B] {
  override def meta = B

  ... // add more fields or methods
}

object B extends B with MongoMetaRecord[B] {
  ...
}

您可以使用 ProtoAuthUser[U] 代替 MongoRecord[U] 或任何其他类似的特征。

It's a late response but maybe someone else will find it useful ;)

abstract class A[U <: A[U]] extends MongoRecord[U] with ... with ObjectIdPk[U] with ... {
  self: U =>

  object text extends StringField(this, 255)

  ... // other fields
}

class B extends A[B] {
  override def meta = B

  ... // add more fields or methods
}

object B extends B with MongoMetaRecord[B] {
  ...
}

You can use ProtoAuthUser[U] in place of MongoRecord[U] or any other similar trait.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文