Swift 不支持将某些协议用作符合另一协议的具体类型

Swift 不支持将某些协议用作符合另一协议的具体类型,swift,protocols,Swift,Protocols,我正在尝试将泛型与协议相结合,我遇到了一个非常困难的xD 我在一个Android/Java项目中实现了特定的体系结构,我正试图重写它,使其适合swift/iOS项目。但我发现了这个局限性 ProtocolA protocol ProtocolA { } class ImplementProtocolA <P : ProtocolA> { let currentProtocol : P init(currentProtocol : P) { se

我正在尝试将泛型与协议相结合,我遇到了一个非常困难的xD

我在一个Android/Java项目中实现了特定的体系结构,我正试图重写它,使其适合swift/iOS项目。但我发现了这个局限性

ProtocolA

protocol ProtocolA {

}
class ImplementProtocolA <P : ProtocolA> {

    let currentProtocol : P

    init(currentProtocol : P) {
        self.currentProtocol = currentProtocol
    }

}
ProtocolB

protocol ProtocolB : ProtocolA {

}
class ImplementProtocolB : ImplementProtocolA<ProtocolB> {

}

protocol ProtocolA {

}
class ImplementProtocolA <P : ProtocolA> {

    let currentProtocol : P

    init(currentProtocol : P) {
        self.currentProtocol = currentProtocol
    }

}
演示者协议

protocol View {

}

protocol GetUserView : View {
    func showProgress()
    func hideProgress()
    func showError(message:String)
    func showUser(userDemo:UserDemo)
}
protocol Presenter {
    typealias V : View
}

class UserDemoPresenter : Presenter {
    typealias V = GetUserView
}
错误:

UserDemoPresenter.swift可能与“V”匹配(又名 “GetUserView”)不符合“视图”

那是什么??符合

即使我使用View而不是GetUserView,它也不会编译

class UserDemoPresenter : Presenter {
    typealias V = View
}
UserDemoPresenter.swift可能与“V”(又名“视图”)匹配 不符合“视图”

我真的不明白

--更新--

罗布·纳皮尔(Rob Napier)提出的解决方案并没有解决这个问题,相反,它只是被推迟了

当尝试定义对UserDemoPresenter的引用时,我需要指定泛型类型,因此会出现相同的错误:

private var presenter : UserDemoPresenter<GetUserView>
private-var-presenter:UserDemoPresenter
使用“GetUserView”作为符合协议的具体类型 不支持“GetUserView”


限制的根本原因是Swift没有一流的元类型。最简单的例子是,这不起作用:

func isEmpty(xs: Array) -> Bool {
    return xs.count == 0
}
理论上,这段代码可以工作,如果可以的话,我还可以制作很多其他类型的代码(比如函子和单子,这在今天的Swift中是无法表达的)。但你不能。你需要帮助斯威夫特把它钉在一个具体的类型。我们通常使用泛型来实现这一点:

func isEmpty<T>(xs: [T]) -> Bool {
    return xs.count == 0
}
这是一个完全抽象的类型,Swift没有任何规则将其转换为具体类型:

class ImplementProtocolB : ImplementProtocolA<ProtocolB>
这仍然是一种抽象类型。你的意思是:

final class Something<T: GetUserView> {
    private var presenter: UserDemoPresenter<T>
}
final class某物{
私有var演示者:UserDemoPresenter
}

如果出现问题,则需要创建一个框。有关如何键入擦除以便保存抽象类型的讨论,请参见。但你需要在具体类型中工作。你不可能最终专门研究一个协议。在大多数情况下,你最终必须专注于具体的事情。

这里也提到:。非常感谢你的解决方案和解释。为了完全理解您的建议,您能否提供一个使用结构而不是类的代码示例?我的意思是用代码中的
struct
替换
class
。如果使用
struct
,您将获得值语义(当您将其传递给函数时,函数将获得其自己的独立副本)。如果需要引用语义(当您将其传递给函数时,调用方会看到函数对其所做的修改),则使用
final class
struct
final类
都禁止子类化,这使得事情变得更容易。(子类化带来了很多疯狂。)好的,谢谢!我要做最后一个类,事实上,它是原始java项目中的最后一个。但我想我将继续使用class而不是struct,我需要这个项目尽可能模仿java项目中定义的行为,改变struct的类可能会导致一个非常大的不同场景xD'这是一个完全抽象的类型,Swift没有任何规则将其转换为具体类型:class ImplementProtocolB:ImplementProtocolA'嘿,Rob,你能详细说明一下这为什么不是具体类型吗?Thanks@MercurialSwift不知道ProtocolB的实际实现,因此无法计算分配多少存储空间来保存“您稍后将传递给我的符合ProtocolB但可能是任意大小的东西”。Swift可以自动创建一个间接框来存储它(这是它处理协议类型变量的方式),但这不是今天Swift的一部分。它需要一个具体的类型(它知道其最终大小)。
private var presenter : UserDemoPresenter<GetUserView>
final class Something<T: GetUserView> {
    private var presenter: UserDemoPresenter<T>
}