Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 作为参数的通用协议以“失败”结尾;无法使用类型为“的参数列表调用”;错误_Swift_Generics_Protocols - Fatal编程技术网

Swift 作为参数的通用协议以“失败”结尾;无法使用类型为“的参数列表调用”;错误

Swift 作为参数的通用协议以“失败”结尾;无法使用类型为“的参数列表调用”;错误,swift,generics,protocols,Swift,Generics,Protocols,我在操场上有这段代码,但它没有编译。错误是无法使用类型为“(uiEvent:MyEvent)”的参数列表调用“actionDispatcher” 以下是代码片段: import UIKit protocol CircuitUiEvent {} protocol CircuitInteractor { associatedtype UiEvent: CircuitUiEvent func actionDispatcher(uiEvent: UiEvent) } enum

我在操场上有这段代码,但它没有编译。错误是
无法使用类型为“(uiEvent:MyEvent)”的参数列表调用“actionDispatcher”

以下是代码片段:

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()
导入UIKit
协议事件{}
协议电路交互器{
associatedtype UiEvent:CircuitUiEvent
func actionDispatcher(uiEvent:uiEvent)
}
枚举MyEvent:CircuitEvent{
凯斯你好
}
类MyInteractor:CircuitInteractor{
typealias UiEvent=MyEvent
func actionDispatcher(uiEvent:MyEvent){
打印(“你好”)
}
}
扩展电路交互器{
func myTestFunction(){
让uiEvent=MyEvent.hello

actionDispatcher(uiEvent:uiEvent)除非我误解了什么,否则您似乎需要将
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()

从远处看问题。让我们从你的基本情况开始:

protocol CircuitUiEvent {}
enum MyEvent: CircuitUiEvent {
    case hello
}
protocol CircuitInteractor {
    associatedtype UiEvent: CircuitUiEvent
    func actionDispatcher(uiEvent: UiEvent)
}
当然,这是可以编译的。现在,CircuitInteractor是一个通用协议,具有一个名为UiEvent的关联类型。因此,现在您尝试将代码插入到带有扩展名的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不能将
self
(p的采用者)的
v
设置为字符串,试图使Assoc成为字符串,从而有效地解析自身

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

protocol P {
    associatedtype Assoc
    var v : Assoc {get set}
}
struct S : P {
    var v : String // <--
}
协议P{
关联类型
var v:Assoc{get set}
}
结构S:P{

var v:String//您的扩展名位于
circuinteractor
上,但不能保证
MyEvent
circuinteractor.UiEvent
的有效类型。您需要扩展
myinteractitor
或在扩展名中添加
where-UiEvent==MyEvent
子句。我认为您可以删除
typeali作为UiEvent=MyEvent
,您不能吗?
func actionDispatcher
的声明解析了泛型。