我正在使用 Ktorm 并嘗試為我的表創建一個抽象和通用的 DAO。最后我得到了型別不匹配,但我看不出我錯在哪里:
BaseEntity 是具有 id 的物體類的介面:
interface BaseEntity<T: Entity<T>>: Entity<T> {
val id: Int
}
用戶(ORM 類):
interface User: BaseEntity<User>
IdTable(以 int id 作為主鍵的表):
open class IdTable<T : BaseEntity<T>>(tableName: String) : Table<T>(tableName) {
val id = int("id").primaryKey().bindTo { it.id }
}
用戶(SQL 表):
object Users : IdTable<User>("users")
基道:
open class BaseDao<E : BaseEntity<E>>(private val es: EntitySequence<E, IdTable<E>>)
UserDao 實作了 BaseDao:
class UserDao(val es: EntitySequence<User, IdTable<User>>) : BaseDao<User>(es)
現在正如 Ktorm 檔案中提到的那樣,我創建了一個 EntitySequence
val Database.users get() = this.sequenceOf(Users)
我想創建一個 UserDao:
userDao = UserDao(database.users)
但我明白了
Type mismatch.
Required:
EntitySequence<User, IdTable<User>>
Found:
EntitySequence<User, Users>
但是Users是IdTable<User>繼承自它的型別。為什么編譯器不知道呢?
uj5u.com熱心網友回復:
我不知道 Ktorm,所以我不會在這部分幫助你,但你的問題是由type variance引起的。是的,您是正確的,Users可以安全地用作IdTable<User>. 但這并不意味著EntitySequence<User, Users>可以用作EntitySequence<User, IdTable<User>>. T的型別引數EntitySequence是不變的,這意味著它既不能向上也不能向下轉換。
為了安全地EntitySequence<User, Users>轉換為EntitySequence<User, IdTable<User>>,T必須是covariant,所以它必須被標記為out引數。但事實并非如此。
事實上,通過查看EntitySequence的定義,我相信T可以/應該將其標記為out. 然后你可以毫無問題地做你需要的事情。也許這只是 Ktorm 中的一個錯誤/疏忽。
如果我是正確的并且T可能是協變的,那么通過進行未經檢查的演員表來解決您的問題也應該是安全的:
userDao = UserDao(database.users as EntitySequence<User, IdTable<User>>)
一個長期的解決方案是將此報告給 Ktorm 開發人員 - 要求他們標記T為out.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/454384.html
