Swift functions. And anonymous Functions

Source: Internet
Author: User
Function

Note: a function that does not define the return type will return a special value called void. It is actually an empty tuple. It can be written as () without any elements ().
Use tuples as return parameters and return multiple parameters

  func count(string: String) -> (vowels: Int, consonants: Int, others: Int) {    var vowels = 0, consonants = 0, others = 0    for character in string {        switch String(character).lowercaseString {        case "a", "e", "i", "o", "u":            ++vowels        case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",          "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":            ++consonants        default:            ++others        }    }    return (vowels, consonants, others)}
External Parameter Name

The External Parameter Name is used to make the parameter more expressive and fluent when calling the function. It also keeps the function body readable and clearly intended. Make it easier for others to read the entire code segment
When others read your code for the first time and the intent of the function parameters is unclear, consider using external parameter names. If the intention of the function parameter name is obvious, you do not need to define the External Parameter Name.

  func join(string s1: String, toString s2: String, withJoiner joiner: String) -> String {      return s1 + joiner + s2  }  join(string: "hello", toString: "world", withJoiner: ", ")

If you need to provide the external parameter name, but the local parameter name has been defined, you do not need to write the parameter name twice. On the contrary, you only need to write the parameter name once and use the # As the prefix. This tells swift to use this parameter name as the local and external parameter names.

  func containsCharacter(#string: String, #characterToFind: Character) -> Bool {    for character in string {        if character == characterToFind {            return true        }    }    return false}
Default Value

Put parameters with default values at the end of the function parameter list. This ensures that the order of non-default parameters is consistent during function calling and makes the same function clearer when it is lowered in different situations.
When you do not provide external parameter names for parameters with default values, swift automatically provides external names. At this time, the external parameter name is the same as the local name, just as you have already written the well number (#) before the local parameter name.

  func join(s1: String, s2: String, joiner: String = " ") -> String {    return s1 + joiner + s2}  join("hello", "world", joiner: "-")// returns "hello-world"
Variable parameters

A variadic parameter can accept one or more values. The value of the passed variable parameter is treated asArray.

  • A function can have a variable parameter at most, and it must be the last one in the parameter table. This is done to avoid ambiguity during function calls.
  • If a function has one or more parameters with default values and a variable parameter, put the variable parameter at the end of the parameter table.
func arithmeticMean(numbers: Double...) -> Double {    var total: Double = 0    for number in numbers {        total += number    }    return total / Double(numbers.count)}
Constant and variable parameters

Function parameters are constants by default.. Changing the parameter value in the function body will cause compilation errors. This means that you cannot mistakenly change the parameter value
Note: modifications to the variable parameters disappear after the function call is completed and are invisible to the function in vitro. Variable parameters only exist in the life cycle of function calls.

Func alignright (VAR string: String, Count: int, pad: character)-> string {Let amounttopad = count-countelements (string) for _ in 1... amounttopad {string = pad + string} return string} // the following error occurs: func test (A: string) {A = "sssss ";}
In-out parameters
  • When defining an input/output parameter, add the inout keyword before the Parameter definition.
  • Input and Output Parameters cannot have default values, and variable parameters cannot be marked with inout. If you use inout to mark a parameter, this parameter cannot be marked by VAR or let.
  • When the input parameter is used as the input and output parameters, you must add the & symbol before the parameter, indicating that the value can be modified by the function.
  func swapTwoInts(inout a: Int, inout b: Int) {    let temporaryA = a    a = b    b = temporaryA}var someInt = 3var anotherInt = 107swapTwoInts(&someInt, &anotherInt);// "someInt is now 107, and anotherInt is now 3”
Function Type

Function type, which allows a variable to become multiple functions. At the same time, you can pass functions as parameters or return values.

var mathFunction: (Int, Int) -> Int = addTwoIntsfunc printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) {    println("Result: \(mathFunction(a, b))")}func chooseStepFunction(backwards: Bool) -> (Int) -> Int {    func stepForward(input: Int) -> Int { return input + 1 }    func stepBackward(input: Int) -> Int { return input - 1 }    return backwards ? stepBackward : stepForward}
Closure
Closures can capture and store references to any constants and variables in their context. This is the so-called closure and enclose these constants and variables, commonly known as closures. Swift manages all memory operations involved in the capture process.
Closures take one of the following three forms:
A global function is a closure with a name but no value is captured.
A nested function is a closure with a name and can capture the values in the function domain.
A closure expression is an anonymous closure that uses lightweight syntax to capture variables or constant values in its context.

Closure expression:

  { (parameters) -> returnType in      statements  }
Closure feature 1: using context inference parameters and return value types

Closure, As a function parameter, can be omitted because of type inference...

  reversed = sorted(names, { (s1: String, s2: String) -> Bool in return s1 > s2 } )  reversed = sorted(names, { s1, s2 in return s1 > s2 } )
Closure Feature 2: the closure of a single expression is returned implicitly, that is, the closure of a single expression can omit the return keyword.

If the package function contains a single expression, you can also save the return statement.

  reversed = sorted(names, { s1, s2 in s1 > s2 } )
Closure feature 3: abbreviated parameter name
  • 1. You can save in
  • 2 operator functions can also be abbreviated
reversed = sorted(names, { $0 > $1 } )reversed = sorted(names, >)
Closure Feature 4: trailing closure syntax

If you need to pass a long closure expression as the last parameter to the function, you can use the trailing closure to enhance the readability of the function. A trailing closure is a closure expression written after the function brackets.Last ParameterCall.

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}
Capture value

Closures can capture constants or variables in the context they define.
Even if the original domain defining these constants and variables does not exist, the closure can still reference and modify these values in the closure function.

Closure is a reference type. Note that when a function in a nested function is used as the return value, a new function is actually created.

// Global function var STR = "Hello, playground" func test (A: String = "") {println (STR)} test (); // "hello, playground "str =" hello "; test (); //" hello "// nested function func makeincrementor (forincrement amount: INT)-> () -> int {var runningtotal = 0 func incrementor ()-> int {runningtotal + = Amount // runningtotal return runningtotal} return incrementor} Let incrementbyten = makeincrementor (forincrement: 10) incrementbyten () // The returned value is 10 incrementbyten () // The returned value is 20 incrementbyten () // The returned value is 30 // because a new function is created .. so let incrementbyseven = makeincrementor (forincrement: 7) incrementbyseven () // The returned value is 7 incrementbyten () // The returned value is 40 // because it is a reference type. so let alsoincrementbyten = incrementbytenalsoincrementbyten () // The returned value is 50.

Note: Swift will decide whether to capture the reference or copy the value. You do not need to mark amount or runningtotal to declare how to use the embedded incrementor function. Swift also processes the memory management operation of the runingtotal variable. If it is no longer used by the incrementor function, it is cleared.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.