The return value

There are functions that return

  • Return string

    func sitename(a) -> String {
        return "Swift Study Notes"
    }
    print(sitename()) // Print swift study notes
    Copy the code

A function that returns no value

  • Void is an empty tuple
  • Three cases: void, empty primitive, no write return
    func sayHello(a) -> Void {
        print("Hello")}// Replace the return value type with an empty primitive ()
    func sayBayBay(a)- > () {print("BayBay")}func sayThanks(a){
        print("Thanks")}Copy the code

The implicit return of the function

  • Don’t write the return

    
    // The function body is an expression a1 + a2, without return
    func sum(a1: Int.a2: Int) -> Int {
        a1 + a2
    }
    sum(a1: 10, a2: 20) / / 30
    Copy the code

Tuples as function return values

  • Return a tuple

    func calculate(num1: Int.num2: Int) -> (sum: Int, difference: Int) {
        let sum = num1 + num2
        let difference = num1 - num2
        return (sum, difference)
    }
    let result = calculate(num1: 30, num2: 10)
    print(result.sum) / / print 40
    print(result.difference) / / print 20
    Copy the code
  • Optional tuples as return values

func fun6 (array: [Int]) -> (min: Int, max: Int)? {
 // Secure processing
 if array.isEmpty { return nil }
 var currentMin = array[0]
 var currentMax = array[0]
 for value in array {
   if value < currentMin {
     currentMin = value
   }
   if value > currentMax {
     currentMax = value
   }
 }
 return (currentMin, currentMax)
}
let result = fun6(array: [8.-6.2.109.3.71])

Copy the code

parameter

Local parameter name

  • Function implementation for internal use
func sample(number: Int) {
   println(number)
}
sample(number: 1) 
sample(number: 2)
sample(number: 3)
Copy the code

External parameter name (parameter label)

  • Used when a function is calledpassTo the function of theparameter
func goToWork(at time: String) {
    print("work time is \(time)")
}
goToWork(at: "9")
Copy the code
  • Instead of writing at, time is used as both the parameter label and the parameter name

use_To omit the argument label of the function

func sum(_ a1: Int._ a2: Int) -> Int {
    a1 + a2
}
sum(10.20)
Copy the code

Default Parameter Value

func check(name: String = "nobody".age: Int.job: String = "none") {
    print("name is \(name), age is \(age), job is \(job)")
}
check(name: "Mars", age: 18, job: "student")
check(name: "Tom", age: 20)
check(age: 20, job: "teacher")
check(age: 10)
Copy the code

Variable parameter

  • A function can have only one variable argument
  • Parameters immediately following a variable parameter cannot omit the parameter label
func sum2(numbers: Int...). -> Int {
    var result = 0
    for number in numbers {
        result + = number
    }
    return result
}
sum2(numbers: 10.20.30.40) / / 100
Copy the code
func test(_ numbers: Int. .str: String._ other: String) {}
test(10.20.30, str: "Mars"."Hello")
Copy the code

Input/output parameter

  • Function parameters in Swift default to let type, constant increment operation,The program will report an error
  • The parameter isValue passedCannot change the value of the variable number
var number = 10
func add(_ num: Int) {
    num + = 1 //error
}
add(2)
Copy the code
  • inoutaddress
  • Inside the function, you can change the value of the external variable number
var number = 10
func add(_ num: inout Int) {
    num + = 1
}
add(&number) / / 11
Copy the code

A function that swaps the values of two variables

func swapValues(_ v1: inout Int._ v2: inout Int) {
    let tmp = v1
    v1 = v2
    v2 = tmp
}
var num1 = 10
var num2 = 20
swapValues(&num1, &num2)
print(num1) // Print out 20
print(num2) // Print out 10
Copy the code
  • usingtuplesSimplify the exchange process
func swapValue(_ v1: inout Int._ v2: inout Int) {
    (v1, v2) = (v2 ,v1)
}
Copy the code
  • It’s already provided in Swiftswap(a: &T, b: &T)Swap the values of two variables

Function types

  • By the function of theThe parameter typesandThe return typeComposition. Function typesNo parameter labels.
func addTwoInts(_ a: Int._ b: Int) -> Int {
    return a + b
}
func printHelloWorld(a) {
    print("hello, world")}// the function types are :(Int, Int) -> Int and () -> Void.
Copy the code
  • Constants or variables are defined as function types
  • Function types as parameter types
  • Function type as return type
static func functionTypesTest(a) {
        print("\n----------------- function: function type test ----------------")
        func addTwoInts(_ a: Int._ b: Int) -> Int { return a + b }
        func multiplyTwoInts(_ a: Int._ b: Int) -> Int { return a * b }
        Int (Int, Int) -> Int (Int, Int, Int)
        
        // If a function does not return a value, the default return value is Void (as explained above), so the following function is of type () -> Void
        func printHelloWorld(a) { print("hello, world")}// Function types can be used as normal types
        var mathFunction: (Int.Int) - >Int = addTwoInts(_:_:) // You can also write addTwoInts without (_:_:)
        print("addTwoInts:", mathFunction(10.10))
        mathFunction = multiplyTwoInts // reassign, now mathFunction refers to multiplyTwoInts
        print("multiplyTwoInts:", mathFunction(10.10))
        let mathFunctionAnother = addTwoInts MathFunctionAnother constant is of type (Int, Int) -> Int
        print("addTwoInts mathFunctionAnother:", mathFunctionAnother(100.100))
        
        Function types can be used as arguments to functions, and function types can also be marked as inout arguments
        func printMathResult(_ mathFunc: (Int.Int) - >Int._ a: Int._ b: Int) {
            print("Function type as parameter", mathFunc(a, b))
        }
        printMathResult(addTwoInts(_:_:), 10.10)
        printMathResult(multiplyTwoInts, 10.10)
        
        // Function type as return value
        func stepForward(_ input: Int) -> Int { return input + 1 }
        func stepBackward(_ input: Int) -> Int { return input - 1 }
        func chooseStepFunction(backward: Bool)- > (Int) - >Int {
            return backward ? stepBackward : stepForward
        }
        print("chooseStepFunction:", chooseStepFunction(backward: true) (10))
        print("chooseStepFunction:", chooseStepFunction(backward: false) (10))}Copy the code

Overloaded function

  • It is used to realize problems with similar functions and different data types
  • Same function name
  • Parameter number different | | parameter types different | | parameters different tags
  • The compiler does not report an error, and the calling method executes the corresponding method
// Different number of parameters
func sum(a1: Int.a2: Int) -> Int {
    a1 + a2
}
func sum(a1: Int.a2: Int.a3: Int) -> Int {
    a1 + a2
}

// Different parameter types
func sum(a1: Int.a2: Double) -> Double {
    Double(a1) + a2
}
func sum(a1: Double.a2: Int) -> Double {
    a1 + Double(a2)
}

// Parameter labels are different
func sum(_ a1: Int._ a2: Int) -> Int {
    a1 + a2
}
func sum(a: Int.b: Int) -> Int {
    a + b
}
Copy the code
  • ** reported an error **
// Different return value types
func sum(a1: Int.a2: Int) -> Int {
    a1 + a2
}
func sum(a1: Int.a2: Int) {
    a1 + a2
}
Copy the code
  • There’s a default argument, the compiler doesn’t give an error, it’s ambiguous, it executes the first function
func sum(a1: Int.a2: Int) -> Int {
    a1 + a2
}
func sum(a1: Int.a2: Int.a3: Int = 10) -> Int {
    a1 + a2 + a3
}

sum(a1: 10, a2: 20)
Copy the code

Nested function

  • Nested functions are invisible to the outside, but can beDirect peripheral functioncall
  • Access controls such as public cannot be used in nested functions
static func nestedFunctions(a) {
        
        func chooseStepFunction(backward: Bool)- > (Int) - >Int {
            func stepForward(input: Int) -> Int { return input + 1 }
            func stepBackward(input: Int) -> Int { return input - 1 }
            return backward ? stepBackward : stepForward
        }
        print("Nested Functions chooseStepFunction:", chooseStepFunction(backward: true) (10))
        print("Nested Functions chooseStepFunction:", chooseStepFunction(backward: false) (10))
        
        func nested1(a) {
            func nested2(a) {
                func nested3(a) {
                    // public func nested4() {} // public access control cannot be used in nested functions
                }
            }
            nested2()
            // nested3() is not visible to nested1. Nested functions are visible only to direct peripheral functions.}}Copy the code

Distributing mechanism

Direct Dispatch (static Dispatch)

  • The CPU calls directly according to the function address, which is the fastest
  • Static dispatch supports both value and reference types
  • Disadvantages of direct distribution: no dynamics, no inheritance support

Table Dispatch (dynamic Dispatch)

  • The function table accesses a pointer to each function implementation
class ParentClass {
    func method1(a) {}
    func method2(a){}}class ChildClass: ParentClass {
    override func method2(a) {}
    func method3(a){}}let obj = ChildClass()
obj.method2()
Copy the code

  • Call the method2() procedure
Read the vtable of this object (0XB00). Read the method2 function pointer0x222Jump to address 0X222, read function implementation.Copy the code

Message Dispatch (dynamic Dispatch)

  • Dynamic dispatch only supports reference types, such as Class, because of the inheritance nature of Class
id returnValue = objc_msgSend(someObject, @selector(messageName:), parameter);

Copy the code

How does Swift distribute functions

  • Value type stuct functions that use direct distribution (because they have no inheritance system)
  • Class objects are distributed using function tables

  • Final: the function cannot be overriddenDirect distributionDoes not appear in vTable
  • Dynamic: The dynamic keyword can be added to functions of both value and reference types
  • Objc: It is possible to expose Swift functions to the objC runtime as function tables for distribution