The Swift Programming Language (Swift 2) -3 Function and Closures
21 September 2015
//: ## Functions and Closures//://: Use `func` to declare a function. Call a function by following its name with a list of arguments in parentheses. Use `->` to separate the parameter names and types from the function’s return type.//:funcgreet(name:String,day:String)->String{return"Hello \(name), today is \(day)."}greet("Bob",day:"Tuesday")//: > **Experiment**://: > Remove the `day` parameter. Add a parameter to include today’s lunch special in the greeting.//://: Use a tuple to make a compound value—for example, to return multiple values from a function. The elements of a tuple can be referred to either by name or by number.//:funccalculateStatistics(scores:[Int])->(min:Int,max:Int,sum:Int){varmin=scores[0]varmax=scores[0]varsum=0forscoreinscores{ifscore>max{max=score}elseifscore<min{min=score}sum+=score}return(min,max,sum)}letstatistics=calculateStatistics([5,3,100,3,9])print(statistics.sum)print(statistics.2)//: Functions can also take a variable number of arguments, collecting them into an array.//:funcsumOf(numbers:Int...)->Int{varsum=0fornumberinnumbers{sum+=number}returnsum}sumOf()sumOf(42,597,12)//: > **Experiment**://: > Write a function that calculates the average of its arguments.//://: Functions can be nested. Nested functions have access to variables that were declared in the outer function. You can use nested functions to organize the code in a function that is long or complex.//:funcreturnFifteen()->Int{vary=10funcadd(){y+=5}add()returny}returnFifteen()//: Functions are a first-class type. This means that a function can return another function as its value.//:funcmakeIncrementer()->(Int->Int){funcaddOne(number:Int)->Int{return1+number}returnaddOne}varincrement=makeIncrementer()increment(7)//: A function can take another function as one of its arguments.//:funchasAnyMatches(list:[Int],condition:Int->Bool)->Bool{foriteminlist{ifcondition(item){returntrue}}returnfalse}funclessThanTen(number:Int)->Bool{returnnumber<10}varnumbers=[20,19,7,12]hasAnyMatches(numbers,condition:lessThanTen)//: Functions are actually a special case of closures: blocks of code that can be called later. The code in a closure has access to things like variables and functions that were available in the scope where the closure was created, even if the closure is in a different scope when it is executed—you saw an example of this already with nested functions. You can write a closure without a name by surrounding code with braces (`{}`). Use `in` to separate the arguments and return type from the body.//:numbers.map({(number:Int)->Intinletresult=3*numberreturnresult})//: > **Experiment**://: > Rewrite the closure to return zero for all odd numbers.//://: You have several options for writing closures more concisely. When a closure’s type is already known, such as the callback for a delegate, you can omit the type of its parameters, its return type, or both. Single statement closures implicitly return the value of their only statement.//:letmappedNumbers=numbers.map({numberin3*number})print(mappedNumbers)//: You can refer to parameters by number instead of by name—this approach is especially useful in very short closures. A closure passed as the last argument to a function can appear immediately after the parentheses. When a closure is the only argument to a function, you can omit the parentheses entirely.//:letsortedNumbers=numbers.sort{$0>$1}print(sortedNumbers)//: [Previous](@previous) | [Next](@next)