Swift 在子协议中指定associatedtype
有没有办法在子协议中定义associatedtype,然后将子协议用作iVar的一种类型 这就是我需要实现的目标: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
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
。您的协议中没有允许弱(我怀疑不应该)啊,注入闭包通常是一个非常好的解决方案。我经常使用一个默认参数来实现这一点,这样普通的调用方就不必提供它,但是单元测试可以。