Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.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 在子协议中指定associatedtype_Swift_Protocols_Associated Types - Fatal编程技术网

Swift 在子协议中指定associatedtype

Swift 在子协议中指定associatedtype,swift,protocols,associated-types,Swift,Protocols,Associated Types,有没有办法在子协议中定义associatedtype,然后将子协议用作iVar的一种类型 这就是我需要实现的目标: protocol Coordinator { associatedtype ResultValue associatedtype ResultError func start(completion: @escaping (Result<ResultValue, ResultError>) -> Void) } protocol Down

有没有办法在子协议中定义associatedtype,然后将子协议用作iVar的一种类型

这就是我需要实现的目标:

protocol Coordinator {
    associatedtype ResultValue
    associatedtype ResultError

    func start(completion: @escaping (Result<ResultValue, ResultError>) -> Void)
}

protocol DownloadPermissionCoordinator: Coordinator {
    associatedtype ResultValue = String
    associatedtype ResultError = DownloadPermissionCoordinatorError
}

protocol SomeOtherCoordinator: Coordinator {
    associatedtype ResultValue = Int
    associatedtype ResultError = SomeOtherCoordinatorError
}

正如您所想象的,SWIFT不认为我的子协调器协议可以用作类型约束。

修改如下:

final class MyTestClass {
    private let downloadPermissionCoordinator: DownloadPermissionCoordinator
    private let someOtherCoordinator: SomeOtherCoordinator

    init(downloadPermissionCoordinator: DownloadPermissionCoordinator,
         someOtherCoordinator: SomeOtherCoordinator) {
        self.coordinator = coordinator
        self.someOtherCoordinator = someOtherCoordinator
    }
}
protocol Coordinator2 {
    func start<ResultValue, ResultError>(completion: @escaping (Result<ResultValue, ResultError>) -> Void)
}
协议协调人2{
函数开始(完成:@escaping(Result)->Void)
}
不幸的是,这不起作用

我试图在具体的协调器协议上避免委托,但似乎我不能有一个通用的闭包。有什么建议吗

p、 为了举例说明协调器的用法,我添加了以下不完整的代码

final class DownloadPermissionCoordinatorImpl: DownloadPermissionCoordinator {
    private let rootViewController: UIViewController
    private let userPermissionService: UserPermissionService

    init(rootViewController: UIViewController,
         userPermissionService: UserPermissionService) {
        self.rootViewController = rootViewController
        self.userPermissionService = userPermissionService
    }

    func start(completion: @escaping (Result<String, ()>) -> Void) {
        guard !userPermissionService.allowsCelularDownload else {
            completion(.success)
            return
        }

        let alertController = ...
        rootViewController.present(alertController, animated: true, completion: nil)
    }
}

extension MyTestClass {
    func doStuffIfAllowed() {
        downloadPermissionCoordinator.start { result in
            switch result {
            case .success: download()
            case .failure: dismiss()
            }
        }
    }
}
最终类DownloadPermissionCoordinatorImpl:DownloadPermissionCoordinator{
私有let rootViewController:UIViewController
私有let userPermissionService:userPermissionService
init(rootViewController:UIViewController,
userPermissionService:userPermissionService){
self.rootViewController=rootViewController
self.userPermissionService=userPermissionService
}
函数开始(完成:@escaping(Result)->Void){
guard!userPermissionService.allowsCelularDownload else{
完成(.success)
返回
}
让alertController=。。。
rootViewController.present(alertController,动画:true,完成:nil)
}
}
扩展MyTestClass{
func dostuffillowed(){
downloadPermissionCoordinator.start{结果为
切换结果{
case.success:下载()
案例.失败:解雇()
}
}
}
}

没有。您几乎肯定根本不需要协议。看起来您可能需要泛型结构,或者更可能只需要闭包。如何实施取决于你的目标。为什么要传递一个“协调器”而不仅仅是传递
start
函数?@RobNapier协调器协议的设计基本上就是确保任何协调器都具有start函数。但是不同的协调器会注入不同的服务以及rootViewController,它们需要是类实例,因为它们可以作为弱parentCoordinator或其他场景传递。@RobNapier我添加了一个用法示例。这与您的协议不匹配。协议中除了
start
方法外,不需要其他任何东西。如果将
DownloadPermissionCoordinatorImpl
传递给接受
DownloadPermissionCoordinator
的方法,则唯一可以调用的方法是
start
。那么为什么不通过
start
。您的协议中没有允许
(我怀疑不应该)啊,注入闭包通常是一个非常好的解决方案。我经常使用一个默认参数来实现这一点,这样普通调用方就不必提供它,但是单元测试可能不需要。你几乎肯定根本不需要协议。看起来您可能需要泛型结构,或者更可能只需要闭包。如何实施取决于你的目标。为什么要传递一个“协调器”而不仅仅是传递
start
函数?@RobNapier协调器协议的设计基本上就是确保任何协调器都具有start函数。但是不同的协调器会注入不同的服务以及rootViewController,它们需要是类实例,因为它们可以作为弱parentCoordinator或其他场景传递。@RobNapier我添加了一个用法示例。这与您的协议不匹配。协议中除了
start
方法外,不需要其他任何东西。如果将
DownloadPermissionCoordinatorImpl
传递给接受
DownloadPermissionCoordinator
的方法,则唯一可以调用的方法是
start
。那么为什么不通过
start
。您的协议中没有允许
(我怀疑不应该)啊,注入闭包通常是一个非常好的解决方案。我经常使用一个默认参数来实现这一点,这样普通的调用方就不必提供它,但是单元测试可以。