Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the syntax for a closure argument in swift

Tags:

closures

swift

In Swift headers, the isSeparator: argument accepts a closure

public func split(maxSplit: Int = default, allowEmptySlices: Bool = default, @noescape isSeparator: (Self.Generator.Element) throws -> Bool) rethrows -> [Self.SubSequence]

But in the documentation, it lists closure syntax differently

{ (parameters) -> return type in
    statements
}

How are you supposed to know that (Self.Generator.Element) throws -> Bool rethrows refers to a closure / requires a closure? Are there other ways that the headers/docs might list argument as meaning a closure?

like image 483
joels Avatar asked Jan 07 '16 22:01

joels


People also ask

What is a closure expression in Swift?

Closure expressions in Swift 4 language follow crisp, optimization, and lightweight syntax styles which includes. Inferring parameter and return value types from context. Implicit returns from single-expression closures. Shorthand argument names and. Trailing closure syntax.

How do you write a closure?

If you need to pass a closure expression to a function as the function's last argument and closure expression is too long, it can be written as trailing closure. A trailing closure is written after the function call's parentheses (), even though it is still an argument to the function.

What is trailing closure syntax in Swift?

Trailing closure syntax should be used for all closure parameters at the end of a parameter list. The use of trailing closure syntax can make the code clearer, but it should only be used when all the closure arguments can be passed as trailing closures.


2 Answers

The "thing" giving away that this is a closure is the ->. The full type is

(Self.Generator.Element) throws -> Bool

It means that the closure takes a variable of type Self.Generator.Element and has to return a Bool upon some calculation based on the input. It may additionally throw some error while doing so - that is what the throws is for.

What you then write

{ (parameters) -> return type in
    statements
}

would be an actual implementation, a value of some generic closure type.

The type of a closure is for example (someInt:Int, someDouble:Double) -> String:

var a : ((someInt:Int, someDouble:Double) -> String)

Once again the thing giving away that a is actually a closure is the -> in the type declaration.

Then you assign something to a via some code snippet following your second code block:

a = { (integer, floating) -> String in
    return "\(integer) \(floating)"
}
like image 180
luk2302 Avatar answered Sep 19 '22 11:09

luk2302


You can tell by the argument's type. Everything in Swift has a type, including functions and closures.

For example, this function...

func add(a: Int, to b: Int) -> Int { return a + b }

...has type (Int, Int) -> Int. (It takes two Ints as parameters, and returns an Int.)

And this closure...

let identity: Int -> Int = { $0 }

...has type Int -> Int.

Every function and closure has a type, and in the type signature there is always a -> that separates the parameters from the return value. So anytime you see a parameter (like isSeparator) that has a -> in it, you know that the parameter expects a closure.

like image 33
Aaron Rasmussen Avatar answered Sep 18 '22 11:09

Aaron Rasmussen