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 called
pass
To 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 is
Value passed
Cannot change the value of the variable number
var number = 10
func add(_ num: Int) {
num + = 1 //error
}
add(2)
Copy the code
inout
address- 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
- using
tuples
Simplify the exchange process
func swapValue(_ v1: inout Int._ v2: inout Int) {
(v1, v2) = (v2 ,v1)
}
Copy the code
- It’s already provided in Swift
swap(a: &T, b: &T)
Swap the values of two variables
Function types
- By the function of the
The parameter types
andThe return type
Composition. 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 be
Direct peripheral function
call - 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 overridden
Direct distribution
Does 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