Functions exist in any language, but Swift is much more flexible.

Definition of function

1.1. Has a return value (the parameter is let by default and can only be let)

func pi() -> Double {

    return 3.14

}

print(PI ()) // Output: 3.14



func sum(v1: Int, v2: Int) -> Int {

    return v1 + v2

}

print(sum(v1: 10, v2: 20)) // Output: 30

Copy the code

1.2. No return value

func hello() -> Void {

    print("hello")

}



func hello() -> () {

    print("hello")

}



func hello() {

    print("hello")

}

Hello () // Output: hello

Copy the code

1.3. If the whole function body is a single expression, the function implicitly returns that expression

func sum(v1: Int, v2: Int) -> Int {

    v1 + v2

}



print(sum(v1: 10, v2: 10)

Copy the code

1.4. Return tuple: Implement multiple return values

func calculate(v1: Int, v2: Int) -> (sum: Int, difference: Int, average: Int) {

    let sum = v1 + v2

    return (sum, v1 - v2, sum >> 1)

}

let result = calculate(v1: 10, v2: 20)

print(result.sum, result.difference, result.average) // Output: 30-10 15

Copy the code

1.5. Parameter labels

Function can modify parameter labels:

// At is called externally and time is used internally

func goToWord(at time: String) {

    print("time is \(time)")

}

goToWord(at: "8")

Copy the code

You can omit parameter labels by using the underscore _ :

func sum(_ v1: Int, _ v2: Int) -> Int { v1 + v2}



sum(10, 20)

Copy the code

1.6. Default Parameter values

  • Parameters can have default values
func check(name: String = "nobody", age: Int, job: String = "none") {

    print("name=\(name), age=\(age), job=\(job)")

}

check(age: 10)

check(name: "Jack", age: 20, job: "Programmer")

check(name: "Eve", age: 18)

check(age: 10, job: "Superman")

/ *

Output:

 name=nobody, age=10, job=none

 name=Jack, age=20, job=Programmer

 name=Eve, age=18, job=none

 name=nobody, age=10, job=Superman

* /

Copy the code
  • C++ default parameters have a limitation: they must be set from right to left and cannot be set across labels; Swift has parameter labels, so there are no such restrictions
  • When omitting parameter labels, pay attention to avoid errors
  • Parameter labels without default values cannot be omitted (such as age above)

1.7. Variable parameters

  • A function can have at most one variable argument
func sum(_ numbers: Int...) -> Int {

    var total = 0

    for number in numbers {

        total += number

    }

    return total

}

let result = sum(10, 20, 30, 40)

print(result) // Output: 100

Copy the code
  • Arguments immediately following mutable arguments cannot omit parameter labels (think: what if they were omitted?).
func test(_ numbers: Int... , string: String, _ other: String) {

    

}

test(10, 20, 30, string: "idbeny"."1024 star")

Copy the code

1.8. Input and output parameters

  • You can use inout to define an input and output parameter: you can modify the values of external arguments inside the function
  • inoutMust and&Together with
  • It’s essentially address passing
  • A variable parameter cannot be marked asinout
  • inoutParameters cannot have default values
  • inoutArguments can only be passed in values that can be assigned more than once

The following changes will result in an error (because the parameter is modified with let)

Use inout and &

var number = 10

func add(_ num: inout Int) {

    num = 20

}

add(&number)

print(number) // Output: 20

Copy the code

In this way, you can also swap the values of two variables.

// Method one (using temporary variables)

func swapValues(_ v1: inout Int, _ v2: inout Int) {

    let temp = v1

    v1 = v2

    v2 = temp

}

var num1 = 10

var num2 = 20

swapValues(&num1, &num2)

print("num1=\(num1), num2=\(num2)"Num1 =20, num2=10



// Method two (using tuples)

var num3 = 30

var num4 = 40

func swapValues1(_ v1: inout Int, _ v2: inout Int) {

    (v1, v2) = (v2, v1)

}

swap(&num3, &num4)

print("num3=\(num3), num4=\(num4)"Num3 =40, num4=30



// Method 3 (system-provided swap function)

var num5 = 50

var num6 = 60

swap(&num5, &num6)

print("num5=\(num5), num6=\(num6)"Num5 =60, num6=50

Copy the code

Second, the documentation of the function

Website: https://swift.org/documentatior/api-design-guidelines

Place the cursor on the corresponding function name and pressOptionYou can view the function description document

  • The sum function description is empty. How to fill in the description?
  • Add a document shortcut (the cursor must be over or above the function) :Command + Option + /

Default document comments

/// <#Description#>

/// - Parameters:

///   - v1: <#v1 description#>

///   - v2: <#v2 description#>

/// - Returns: <#description#>

func sum(v1: Int, v2: Int) -> Int { v1 + v2}

Copy the code

More detailed documentation comments (Summary and detail must be separated, otherwise it defaults to detail)

// add two integers together

///

// add two integers together

/// - Parameters:

/// -v1: the first argument

/// -v2: the second parameter

/// - Returns: the sum of two parameters

/// - Note: pass in 2 integers

func sum(v1: Int, v2: Int) -> Int { v1 + v2}

Copy the code

The effect

Function overloading

  • OC does not support function overloading, but Swift does
  • The rules
    • Same function name
    • Parameter number different | | parameter types different | | parameters different tags

All of the following functions constitute function overloads and can be called without conflicts:

/ / reference

func sum(v1: Int, v2: Int) {

    v1 + v2

}



// Different number of parameters

func sum(v1: Int, v2: Int, v3: Int) {

    v1 + v2 + v3

}



// Different parameter types

func sum(v1: Int, v2: Double) {

    Double(v1) + v2

}



// Different parameter labels (ignore labels)

func sum(_ v1: Int, _ v2: Int) {

    v1 + v2

}



// Different parameter labels (different label names)

func sum(a: Int, b: Int) {

    a + b

}

Copy the code
  • The return value type is independent of function overloading

  • The compiler does not error when using default parameter values with function overloading to produce ambiguities (it does in C++)

func sum(v1: Int, v2: Int) -> Int {

    v1 + v2

}



func sum(v1: Int, v2: Int, v3: Int = 30) -> Int {

    v1 + v2 + v3

}



Sum (v1: 10, v2: 20) // Output: 30

Copy the code
  • Variable arguments, omit parameter labels, and function overloading are used together to produce ambiguity when the compiler hasMay beAn error

Why is it possible to report errors? (The following code can execute normally, so it is not recommended in normal development.)

func sum(_ v1: Int, _ v2: Int) -> Int {

    v1 + v2

}



func sum(_ numbers: Int...) -> Int {

    var total = 0

    for num in numbers {

        total += num

    }

    return total

}



Sum (10, 20) // Output: 30

Copy the code

4. Function types

Each function has a type. Function types consist of formal parameter types and return value types:

  • Function types can be passed as function parameters;
  • Function types can be returned as function values;
  • A function whose return value is a function type is called a higher-order function.

5. Nested functions

To define a function inside a function:

func foward(_ forward: Bool) -> (Int) -> Int {

    func next(_ input: Int) -> Int {

        input + 1

    }

    func previous(_ input: Int) -> Int {

        input - 1

    }

    return forward ? next : previous

}

foward(true(1) // Output: 2

foward(false(2) // Output: 1

Copy the code

6. Inline functions

If compiler optimization is enabled (Release mode is enabled by default), the compiler automatically inlines certain functions:

  • Release is optimized for fast running by default;
  • Debug can also be enabled manually, but is generally disabled for easy debugging during development.

What does an inline function do?

  • Inline functions often appear in C++. If a function is an inline function, the compiler will put the code in the appropriate code block in the corresponding position during compilation to improve the efficiency of code execution
  • Expand a function call into a function body
func test() {

    print("test")

}

test(a)

Copy the code
  • If the above code is turned on compiler optimization,test()Will be replaced with theprint("test").

Not all inlined functions are expanded by the compiler. Which functions are not inlined?

  • The body of the function is longer
  • Contains recursive calls
  • Include dynamic distribution

@inline: never inlined (even if compiler optimization is turned on)

@inline(never) func test() {

    print("test")

}

Copy the code

When compiler optimization is enabled, even long code will be inlined (except for functions that are called recursively and distributed dynamically) :

@inline(__always) func test1() {

    print("test")

}

Copy the code
  • In Release mode, the compiler already has optimization on and automatically decides which functions need to be inlined, so it’s not necessary@inline.