Am I missing something here? I cannot see a reason that this would not compile...
protocol StringValidationRule { func validate(string: String) throws -> Bool var errorType: StringValidationError { get } } extension Array where T: StringValidationRule { func validateEach(string: String, completion: (valid: Bool, error: StringValidationError?) -> ()) { for rule in self { do { try rule.validate(string) completion(valid: true, error: nil) } catch let error as StringValidationError { completion(valid: false, error: error) } catch { fatalError("Unexpected error type") } } } } var validationRules = ... validationRules.validateEach("") { (valid, error) -> () in }
Line 23 throws the following error:
error: cannot invoke 'validateEach' with an argument list of type '(String, (_, _) -> ())'
validationRules.validateEach("") { (valid, error) -> () in
AFAIK, extensions with where clauses only work with protocols. So, instead of extending Array, I would extend the CollectionType protocol. This way, your logic will work for all implementations of CollectionType, including Array.
The code is below. You can try it out in a Swift 2 playground.
typealias StringValidationError = String protocol StringValidationRuleType { func validate(string: String) throws -> Bool } extension CollectionType where Generator.Element: StringValidationRuleType { func validateEach(string: String, completion: (valid: Bool, error: StringValidationError?) -> ()) { for rule in self { do { try rule.validate(string) completion(valid: true, error: nil) } catch let error as StringValidationError { completion(valid: false, error: error) } catch { fatalError("Unexpected error type") } } } } struct StringValidationRule: StringValidationRuleType { let valid: Bool func validate(string: String) throws -> Bool { return true } } var validationRules = [StringValidationRule(valid: true), StringValidationRule(valid: true)] validationRules.validateEach("") { (valid, error) -> () in { }}
== Matthias