【发布时间】:2018-04-11 19:15:38
【问题描述】:
我在我的 iOS 应用程序中使用 Realm,由于线程安全问题,我选择为我的数据模型创建一个领域层,以及一个可以与领域对象相互转换的层。
我实际在做的事情要复杂得多,但我能够创建一个游乐场来展示我遇到的意外问题。
基本上我创建了一个名为 RealmObject 的协议。在我的实际应用中,这是 Realm.Object 类型可以遵循的协议,它需要所有必要的属性。
我只是在 Playground 中包含此协议的 UUID 部分。
//the realm layer
protocol RealmObject {
var uuid: String { get }
}
接下来我有我的领域层模型。它们都有 UUID,但还有一些其他属性对应于它们的非 Realm 亲属。
struct NoteObject: RealmObject {
let uuid: String
let noteText: String
}
struct AppointmentObject: RealmObject {
let uuid: String
let time: Date
}
Cacheable 是可以保存在领域中的类型必须遵守的协议。 现在我刚刚包含了 UUID 要求,以及从 RealmObject 初始化的要求
//Cacheable
protocol Cacheable {
associatedtype T: RealmObject
init(object: T)
}
struct Note: Cacheable {
let noteText: String
let uuid: String
init(object: NoteObject) {
self.uuid = object.uuid
self.noteText = object.noteText
}
}
struct Appointment: Cacheable {
let uuid: String
let time: Date
init(object: AppointmentObject) {
self.uuid = object.uuid
self.time = object.time
}
}
最后是问题。在我的应用程序中,此功能的功能远不止于此,但这就像我可以做到的那样简单,并且仍然可以演示问题。 基本上, T 是必须是可缓存对象的泛型类型。 U 是我要转换为可缓存对象的 RealmObject。
每个 Cacheable 对象都有一个初始化器,它接受一个 RealmObject 对象
但是失败了
func getCacheable<T: Cacheable, U: RealmObject>(from realmObject: U) -> T {
let thing = T(object: realmObject)
ERROR: Non-nominal type 'T' does not support explicit initialization
return thing
}
let noteObject = NoteObject(uuid: "bobalobla", noteText: "hi how are you")
let note: Note = getCacheable(from: noteObject)
let appointmentObject = AppointmentObject(uuid: "bobloblaw", time: Date())
let appointment: Appointment = getCacheable(from: appointmentObject)
我没有看到任何如此模棱两可的东西,编译器应该无法轻易弄清楚
用类型替换泛型应该很简单
一旦函数知道它使用的是哪个 Cacheable 类型,初始化器应该很容易被路由到正确的 init 方法。我不会假装理解实际发生的事情,但这似乎是与泛型有关的非常基本的事情,所以我认为我一定做错了什么。怎么回事?
【问题讨论】:
-
我在这里可能完全错了,这就是我评论而不是回答的原因,但是用
T.init(object: realmObject)替换T(object: realmObject)有效果吗? -
@Connor Cannot invoke 'init' with an argument list of type '(object: U)' 是抛出的错误。值得注意的是,我还尝试将 T.Type 作为函数参数传入,所以基本上是
type: T.Type,然后是type(object: realmObject),但这会在我的标题中引发完全相同的错误 -
U不一定是T.T- 您需要将T.T传递给T的init(object:)(即用T.T替换函数的U参数)。