Swift泛型初始化:非名义类型' T'不支持显式初始化

时间:2018-04-11 19:15:39

标签: swift generics

我在我的iOS应用程序中使用Realm,并且由于线程安全问题,我选择为我的数据模型创建一个领域层,以及一个可以转换为realm对象的层。

我实际上做的事情要复杂得多,但我能够创建一个游乐场,展示我遇到的意外问题。

基本上我创建了一个名为RealmObject的协议。在我的实际应用程序中,这是一个Realm.Object类型可以符合的协议,它需要所有必需的属性。

我只是将这个协议的UUID部分包含在游乐场中。

//the realm layer
protocol RealmObject {
    var uuid: String { get }
}

接下来我有我的Realm图层模型。它们都有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是泛型类型,它必须是Cacheable对象。 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方法。我不会假装了解实际发生的事情,但这对于泛型来说似乎是一个非常基本的事情所以我认为我必须做错事。发生了什么事?

1 个答案:

答案 0 :(得分:1)

类型系统无法从您的通用列表<T: Cacheable, U: RealmObject>中知道URealmObject的{​​{1}}的正确类型(换句话说,您可能会将T传递为Note,将T传递为AppointmentObject。您只需将功能签名更新为:

U