💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## Closures Global and nested functions, as introduced in Functions, are actually special cases of closures. Closures take one of three forms: * Global functions are closures that have a name and do not capture any values. * Nested functions are closures that have a name and can capture values from their enclosing function. * Closure expressions are unnamed closures written in a lightweight syntax that can capture values from their surrounding context. Closure expression syntax has the following general form: ~~~ { (parameters) -> return type in statements } ~~~ ~~~ let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella”] func backwards(s1: String, s2: String) -> Bool { return s1 > s2 } // 方法1 var reversed = sort(names, backwards) // reversed is equal to ["Ewa", "Daniella", "Chris", "Barry", "Alex”] // 1.5 reversed = sort(names, { (s1: String, s2: String) -> Bool in return s1 > s2 } ) // 方法2 reversed = sort(names, { s1, s2 in return s1 > s2 } ) // 方法3 reversed = sort(names, { s1, s2 in s1 > s2 } ) // Implicit Returns from Single-Expression Closures // 方法4 reversed = sort(names, { $0 > $1 } ) // 方法5 reversed = sort(names, >) // 方法6 reversed = sort(names) { $0 > $1 } ~~~ It is always possible to infer parameter types and return type when passing a closure to a function as an inline closure expression. As a result, you rarely need to write an inline closure in its fullest form. ~~~ func someFunctionThatTakesAClosure(closure: () -> ()) { // function body goes here } // here's how you call this function without using a trailing closure: someFunctionThatTakesAClosure({ // closure's body goes here }) // here's how you call this function with a trailing closure instead: someFunctionThatTakesAClosure() { // trailing closure's body goes here } ~~~ If a closure expression is provided as the function’s only argument and you provide that expression as a trailing closure, you do not need to write a pair of parentheses () after the function’s name when you call the function. ~~~ let digitNames = [ 0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four", 5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine" ] let numbers = [16, 58, 510] let strings = numbers.map { (var number) -> String in var output = "" while number > 0 { output = digitNames[number % 10]! + output number /= 10 } return output } // strings is inferred to be of type String[] // its value is ["OneSix", "FiveEight", "FiveOneZero"] ~~~ ~~~ func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor } let incrementByTen = makeIncrementor(forIncrement: 10) incrementByTen() // returns a value of 10 incrementByTen() // returns a value of 20 incrementByTen() // returns a value of 30 let incrementBySeven = makeIncrementor(forIncrement: 7) incrementBySeven() // returns a value of 7 incrementByTen() // returns a value of 40 let alsoIncrementByTen = incrementByTen alsoIncrementByTen() // returns a value of 50 ~~~ functions and closures are reference types.