Normally, when passing a closure as the only argument in a function call, you can move the closure outside the argument list and then discard the empty argument list. However, using Xcode 11.4.1, in this code
init?(id: String) {
guard id.allSatisfy { $0.isASCII } else {return nil }
I get the error messages
Cannot convert value of type '((String.Element) throws -> Bool) throws -> Bool' (aka '((Character) throws -> Bool) throws -> Bool') to expected condition type 'Bool'
Expected 'else' after 'guard' condition
Anonymous closure argument not contained in a closure
If I put parentheses around the closure, turning it back into an ordinary argument, the compiler is happy.
Is this some language restriction I'm not familiar with?
atfelix
(Adam Felix)
3
The issue is that Swift thinks your { $0.isASCII } needs an else before it. When using closures with conditional statements, you must wrap them in the parentheses otherwise the parser (I believe) will fail. This below code should work
init?(id: String) {
guard id.allSatisfy({$0.isASCII }) else { return nil }
You will need to do this wrapping inside while conditions, and if conditions as well.
You could also use key path expressions as function syntax
init?(id: String) {
guard id.allSatisfy(\.isASCII) else { return nil }
1 Like
OK, I suppose that makes sense. It’s just a minor inconvenience. Thanks.