通用协议作为参数失败,并显示“无法使用类型的参数列表调用”错误

时间:2018-06-19 20:52:20

标签: swift generics protocols

我在操场上有此代码,但无法编译。错误为Cannot invoke 'actionDispatcher' with an argument list of type '(uiEvent: MyEvent)'

这是代码段:

import UIKit

protocol CircuitUiEvent {}

protocol CircuitInteractor {

    associatedtype UiEvent: CircuitUiEvent

    func actionDispatcher(uiEvent: UiEvent)
}

enum MyEvent: CircuitUiEvent {
    case hello

}

class MyInteractor: CircuitInteractor {

    typealias UiEvent = MyEvent

    func actionDispatcher(uiEvent: MyEvent) {
        print("Hello")
    }
}

extension CircuitInteractor {

    func myTestFunction() {
        let uiEvent = MyEvent.hello
        actionDispatcher(uiEvent: uiEvent) <--- this line throws the error
    }
}

let interactor = MyInteractor()
interactor.myTestFunction()

有什么想法吗?我需要的是一个符合要作为参数传递的协议的枚举,因此我可以有一个简单的API定义,根据它的使用位置或背后的模型,它可以使用不同的switch语句。

2 个答案:

答案 0 :(得分:1)

除非我有误解,否则似乎您需要将myTestFunction移至MyInteractor类,因为它是一个使用具体事件类型的函数,而CircuitInteractor使用的是通用协议。也许,像这样的事情会有意义吗?

protocol CircuitUiEvent {}

protocol CircuitInteractor {
  associatedtype UiEvent: CircuitUiEvent
  func actionDispatcher(uiEvent: UiEvent)
}

extension CircuitInteractor {
  func actionDispatcher(uiEvent: UiEvent) {
    print(uiEvent)
  }
}

enum MyEvent: CircuitUiEvent {
  case hello
}

class MyInteractor: CircuitInteractor {
  typealias UiEvent = MyEvent
  func myTestFunction() {
    self.actionDispatcher(uiEvent: .hello)
  }
}

let interactor = MyInteractor()
interactor.myTestFunction()

答案 1 :(得分:0)

再远一点看问题。让我们从您的基本情况开始:

protocol CircuitUiEvent {}
enum MyEvent: CircuitUiEvent {
    case hello
}
protocol CircuitInteractor {
    associatedtype UiEvent: CircuitUiEvent
    func actionDispatcher(uiEvent: UiEvent)
}

那当然可以编译。现在,CircuitInteractor是一种通用协议,其关联类型为UiEvent。因此,现在您尝试将 code 插入具有扩展名的CircuitInteractor中:

extension CircuitInteractor {
    func myTestFunction() {
        actionDispatcher(uiEvent: MyEvent.hello)
    }
}

您要在这里做什么? MyEvent.hello在泛型的参数化类型的点即期望的UiEvent处传递。因此,显然您正在尝试解析通用。但这是协议中的代码通用协议无法解决本身!

这是您要说的话的简化形式:

protocol P {
    associatedtype Assoc
    var v : Assoc {get set}
}
extension P {
    mutating func f() {
        self.v = "hello"
    }
}

那是废话-与您的代码相同。 P不能将v中的self(P的 )设置为字符串,以使Assoc成为String,从而有效地解决自身问题。

可以解析通用协议?协议的采用者

protocol P {
    associatedtype Assoc
    var v : Assoc {get set}
}
struct S : P {
    var v : String // <--
}