理解Scala中自类型和类型边界之间的交互

理解Scala中自类型和类型边界之间的交互,scala,circumflex-orm,Scala,Circumflex Orm,我以前试过把这个问题分解成更小、更简单的问题,但我意识到这些问题的答案,虽然在技术上是正确的,但并不能帮助我理解这个特殊的案例 我使用的是一个库,它允许您按如下方式定义模式: class User extends Record[Int, User] { val name = "name".TEXT val age = "age".INTEGER def relation = User } object User extends User with Table[Int, User]

我以前试过把这个问题分解成更小、更简单的问题,但我意识到这些问题的答案,虽然在技术上是正确的,但并不能帮助我理解这个特殊的案例

我使用的是一个库,它允许您按如下方式定义模式:

class User extends Record[Int, User] {
  val name = "name".TEXT
  val age = "age".INTEGER
  def relation = User
}
object User extends User with Table[Int, User]
这是因为在记录范围内有一个隐式视图:

abstract class Record[PK, R <: Record[PK, R]] extends Equals { this: R =>
  implicit def view(x: String) = new DefinitionHelper(x, this)
  ...
}

class DefinitionHelper[R <: Record[_, R]](name: String, record: R) {
  def TEXT = ...
  def INTEGER = ...
  ...
}
我不想把这个隐式引入任何其他作用域 除了记录定义之外

import Implicits._
class User extends Record[Int, User] { ... }
所以一个想法是将Record子类化(或引入mixin),然后定义 通过扩展MyRecord而不是Record(或始终 在MyMixin中混合)

我首先尝试:

abstract class MyRecord[PK, R <: MyRecord[PK, R]]
extends Record[PK, R] {
  implicit def str2ddlHelper2(str: String) =
    new DefinitionHelper(str, this)
}
所以我试着:

abstract class MyRecord[PK, R <: MyRecord[PK, R]]
extends Record[PK, MyRecord[PK, R]] {
 implicit def str2ddlHelper2(str: String) =
   new DefinitionHelper(str, this)
}
错误是:

inferred type arguments [User] do not
conform to class DefinitionHelper's type parameter bounds [R <:
ru.circumflex.orm.Record[_, R]]

type mismatch;  found   : User.type (with
underlying type object User)  required:
ru.circumflex.orm.Relation[Int,MyRecord[Int,User]]
Note: User <:
MyRecord[Int,User] (and
User.type <:
ru.circumflex.orm.Table[Int,User]), but
trait Relation is invariant in type R. You may wish to define R as +R
instead. (SLS 4.5)
推断类型参数[User]不存在

符合类定义帮助器的类型参数界限[R您的第一个错误是比较简单的错误,并且很容易通过您的最终解决方案解决。声明中的self-type
R=>

Record[PK, R <: Record[PK, R]] extends Equals { this: R =>
它应该可以工作(我在一个非常接近你的代码的例子上做了这个,但实际上没有使用扬抑)。为什么编译器不推断,我不知道。无论如何,你的
User
不是
Record[Int,User]
而是
Record[Int,MyRecord[Int,User]]
肯定会引起问题。实际解决方案要简单得多

illegal inheritance;  self-type MyRecord[PK,R] does not conform to ru.circumflex.orm.Record[PK,R]'s selftype R
abstract class MyRecord[PK, R <: MyRecord[PK, R]]
extends Record[PK, MyRecord[PK, R]] {
 implicit def str2ddlHelper2(str: String) =
   new DefinitionHelper(str, this)
}
class User extends MyRecord[Int, User] {
 val id = "id".INTEGER
 val value = "value".BYTEA // works
 val value2 = new DefinitionHelper("", this) // does not work?!
 ...
 def relation = User // another error here
}
object User extends User with Table[Int, User]
inferred type arguments [User] do not
conform to class DefinitionHelper's type parameter bounds [R <:
ru.circumflex.orm.Record[_, R]]

type mismatch;  found   : User.type (with
underlying type object User)  required:
ru.circumflex.orm.Relation[Int,MyRecord[Int,User]]
Note: User <:
MyRecord[Int,User] (and
User.type <:
ru.circumflex.orm.Table[Int,User]), but
trait Relation is invariant in type R. You may wish to define R as +R
instead. (SLS 4.5)
abstract class MyRecord[PK, R <: MyRecord[PK, R]]
extends Record[PK, R] { this: R =>
  implicit def str2ddlHelper2(str: String) =
    new DefinitionHelper(str, this)
}
Record[PK, R <: Record[PK, R]] extends Equals { this: R =>
new DefinitionHelper[MyRecord[Int, User]]("", this)