我以前試圖將這個問題分解成更小,更簡單的問題here和here,但我意識到這些技術上正確的答案並沒有幫助我理解這個特定案件。瞭解在自我類型和類型邊界之間的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]
這工作,因爲這是在-範圍內記錄的隱含觀點:
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 = ...
...
}
我正在嘗試引入一種新的擴展方法以及稱爲BYTEA的TEXT等。所以我知道我需要我自己的隱式輔助類:
class DefinitionHelper[R <: Record[_, R]](name: String, record: R) {
def BYTEA = new BytesField[R](name, record)
}
現在我需要在範圍上一個隱含每當我定義新的記錄,但 我不想每次都寫一個import語句:
class User extends Record[Int, User] {
import Implicits._
...
}
除了記錄定義之外,我不想將此隱式引入到任何其他範圍 。
import Implicits._
class User extends Record[Int, User] { ... }
那麼一個想法是繼承記錄(或引進一個mixin),然後通過延長MyRecord而不是記錄定義 我的架構記錄(或總是 在MyMixin混合)。
class User extends MyRecord[Int, User] { ... }
我第一次嘗試:
abstract class MyRecord[PK, R <: MyRecord[PK, R]]
extends Record[PK, R] {
implicit def str2ddlHelper2(str: String) =
new DefinitionHelper(str, this)
}
這將產生:
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)
}
我很好奇,想知道剛剛發生了什麼在這裏,作爲以及也許還有一些例子可以幫助我更好地把事情圍繞在更好的事情上,這樣我就不會覺得我總是「擺弄,直到它工作」。
問題標題的道歉 - 不確定它是否有意義。