1. The function
1.1 Function Format:
1). Multiple returns: func function name (parameter name: parameter type…) -> (Return value type…) {} 2). Single return value: func function name (parameter name: parameter type…) -> Return value type {} 3). No return value: func function name (parameter name: parameter type,…) -> () or func function name (parameter name: parameter type,…) Public TypeAlias Void = () public TypeAlias Void = ()
1). The default parameter is let and can only be let; 2). Implement multiple function return values, using the Tuple type in Swift
1.2 Initial Parameter Values
Parameter Settings Initial Value Parameter name: Parameter type = Initial value
func person(name:String ,age : Int.job : String = "free worker"){
print("name = \(name),age = \(age),job = \(job)")}Copy the code
After declaring the function above, you can see when calling the function:
A parameter with an initial value may or may not be passed a value when the function is called.
1.3 Variadic Parameter
Format: Parameter Name: Parameter Type…
Note: 1). Only one variable argument can exist in each function; 3). The parameter name of a variable parameter can be omitted. 4). Omit parameter labels and variable parameter types are the same, do not declare consecutively, it is difficult to distinguish which parameter is given
func makeSentence(words : String. .other:String) -> String{
var sentence = ""
for word in words {
sentence = sentence + "" + word
}
sentence = sentence + other
return sentence
}
makeSentence(words: "Function"."having"."Variadic parameters"."Add as many strings here you want"."Can use one variadic parameter per func"."Make full use",other:".")
Copy the code
1.4 Argument Label
Parameter labels can be modified; 1). The parameter label format is: func function name (parameter label parameter name: parameter type…) -> (return list){}
2). Omit parameter label format: func function name (_ parameter name: parameter type,…) -> (return list){} This time after the declaration of the function instance variable, the parameter name is not displayed.
1.5 Implicit Return
If the entire function body is a single expression, the function implicitly returns the entire expression, in which case the return keyword can be omitted.
An 🌰 :
func sum(v1 : Int.v2 : Int) -> Int{
v1 + v2
}
Copy the code
The sum function is v1 + v2; Is a single expression that can omit the return keyword.
1.6 Function Overload
Function overloading rules: 1). The function name is the same as 2). The number of parameters of different | | parameter types different | | parameters different tags
An 🌰 :
/ / function
func sum(v1:Int.v2:Int)-> Int{
v1 + v2
}
// Parameter labels are different
func sum(_ v1 : Int._ v2 : Int) -> Int{
v1 + v2
}
func sum(a : Int.b : Int) -> Int{
a + b
}
// Different number of parameters
func sum(v1:Int.v2:Int.v3:Int)-> Int{
v1 + v2 + v3
}
// Different parameter types
func sum(v1:Int.v2:Double) -> Double{
Double(v1) + v2
}
func sum(v1:Double.v2:Int)-> Double{
v1 + Double(v2)
}
Copy the code
Tips: Return value types are independent of function overloading
func sum(v1:Int.v2:Int) -> Int{v1+v2}
func sum(v1:Int.v2:Int){}
sum(v1:10,v2:20)// Error: Ambiguous use of sum(v1:v2)
Copy the code
The above return values are of different types and do not constitute function overloading.
1.6 Using Functions
Function types are composed of the following types: formal parameter types, return value types function types can be parameters, return value;
1.6.1 Functions are defined as variables and constants
An 🌰 :
/ / square
func square(_ num : Int) -> Int{
return num * num
}
square(4)
/ / cubic
func cube(_ num : Int) -> Int{
return num * num * num
}
cube(4)
// You can assign a function to a variable or constant in the same way as square
var exponentialFunction = square
exponentialFunction(4)
// Print the result: 16
cube(exponentialFunction(4))
// Print the result: 4092
Copy the code
1.6.2 Function as input parameter
var integers = [1.2.3.4.5]
func sumOfExponentialsOf(array a: [Int].with function: (Int) - >Int)->Int
{
var result = 0
for x in a
{
result = result + function(x)
}
return result
}
sumOfExponentialsOf(array: integers, with: exponentialFunction)
// Print the result: 55
Copy the code
1.6.2 Function as return
A Function whose return type is a Function is called higher-order Function.
1. Nested Function
To define a function inside a function is called a nested function
For example 🌰 : define a function that returns a value of type function and has nested functions inside
func chooseComputation(isSquared b : Bool)- > (Int) - >Int{
func square(_ num :Int)->Int// Nested functions
{
return num*num
}
func cube(_ num :Int)->Int
{
return num*num*num
}
if b {
return square
}
else{
return cube
}
}
var result = chooseComputation(isSquared: true)//result is a function of type (Int)->(Int)
result(2) // Print the result: 4
result = chooseComputation(isSquared: false)
result(2) // Print the result: 8
let value = chooseComputation(isSquared: true) (5)// Value is an Int, and the output is 25
Copy the code
2. The structure of the body
In Swift, most common types are structures, including Bool, Int, Double, String, Array, Dictionary, and other common types. The structure has several distinct characteristics:
Feature 1: All constructs have an initializer (initializer, initializer, constructor, constructor) automatically generated by the compiler.
struct Rectangle{
var width
var height
}
var rectangle = Rectangle.init(width: 10, height: 10)
Copy the code
Attribute 2: Depending on the situation, the compiler may generate multiple initializers for a structure. The purpose is to ensure that all members have initial values.
An 🌰 1:
struct Rectangle{
var width : Int = 10
var height : Int
}
// Initial method 1:
var rectangle = Rectangle(width: 20, height: 20)
// Initial method 2:
var rectangle2 = Rectangle(height: 10)
Copy the code
For example, 🌰2: width and height are nil by default, equivalent to struct member variables having values
struct Rectangle{
var width : Int?
var height : Int?
}
// Initial method 1:
var rectangle = Rectangle(width: 20, height: 20)
// Initial method 2:
var rectangle2 = Rectangle(height: 10)
// Initial method 3:
var rectangle3 = Rectangle(a)Copy the code
Attribute 3: If the initialized structure is a constant, it cannot be changed, even if the structure members are variables
let rectangleConstant = Rectangle()
rectangleConstant.height = 20/ / an error
rectangleConstant.width = 20/ / an error
Copy the code
Attribute 4: If the initialized structure is a variable and the structure members are constants, the structure members cannot be changed
struct Circle{
let radius : Int = 0
}
var circle = Circle()
circle.radius = 10/ / an error
Copy the code
Feature 4: Once you define an initializer when defining a structure, the compiler does not automatically generate additional initializers for the structure.
Class 3.
2) The class definition is similar to the structure, but the compiler does not automatically generate initializers for the class that can pass in member values. 3) If all members of a class have specified initializers when they are defined, the compiler generates an initializer with no parameters for the class. 4) The memory of the class stores: reference type information (8 bytes) + reference count (8 bytes) + variable; Methods in a class are not stored in the class’s memory. 5) The class memory alignment coefficient is 16.
4. The difference between structures and classes
1) Structs are value types (enumerations are also value types) and classes are reference types (pointer types); 2) Compilation automatically generates initialization methods for structs; 3) The internal storage of the structure may not be in the stack space, depending on where the structure variable is defined. If the structure variable is defined in a function, the structure variable is in the stack space. 4) The declared class variable is a pointer variable that points to the class stored in the heap. Classes must exist in heap space, class variables may not, depending on where class variables are defined.
5. Value types & reference types
5.1 value type
2) In order to improve the performance, String, Array, Dictionary, and Set adopt the technology of copy On Write. A copy operation is performed only when a write operation is performed. 3) Value types include: enumeration (Optional), structure (Bool, Int, Float, Double, Character), Array, Dictionary, Set.
5.2 Reference Types
- Class is a reference type
- When a reference is assigned to a var, let, or function, it makes a shallow copy of the memory address.
6. Closure
Functions are also a type of closure; Closures are functions that have no name and no func keyword.
6.1 Closure Expressions
Closure expressions:
{(parameter list) -> Return value typeinFunction body code}Copy the code
Additional: 1) Omit the return value type part when there is no return value, or the return value type can be inferred from the context; 2) Omit the argument list section of the code when there is no input parameter, or when the input parameter type can be inferred from the context
6.2 Trailing closures
A trailing closure is a closure expression written outside (after) the function call parentheses. Map and sorted are also trailing closures.
// Convert an integer array to a character array
var numbersArray = [1.2.3.4.5.6]
var closureString = numbersArray.map{
return "\ [$0)"
}
print(closureString)// Print result: ["1", "2", "3", "4", "5", "6"]
// Sort arrays in descending order using trailing closures
var descendingArray = numbersArray.sorted{$0 > The $1}
print(descendingArray)// Print the result: [6, 5, 4, 3, 2, 1]
Copy the code
6.3 Escape (escape) closure
1) Escape closure: a closure passed to a function that will not be called until the function has finished executing. In other words, it outlives the function passed to it. Escape closures are typically used to complete handlers because they are called after the function ends. 2) Non-escaped closure: the closure of the passed function that will be called during the execution of the function, i.e. before it returns. Closures are not escaped by default and require the key @escaping modifier.
6.4 Automatic Closures (@AutoClosure)
An automatic closure is a closure that is automatically created to package expressions passed to functions as actual arguments. It takes no actual arguments, and when it is called, it returns the value of the internally packaged expression. The nice thing about this syntax is that it lets you omit the parentheses of function-form arguments by writing plain expressions instead of showing closures. An 🌰 :
// @autoclosure was not added
func getFirstPositive(_ v1:Int._ v2: () - >Int) -> Int? {return v1 > 0 ? v1 : v2()
}
getFirstPositive(-4) {20}
// Add @autoclosure
func getFirstPositive(_ v1:Int._ v2:@autoclosure() - >Int) -> Int? {return v1 > 0 ? v1 : v2()
}
getFirstPositive(-4.20)
Copy the code
Additional: @AutoClosure only supports arguments in ()-> T format; Null merge operator?? Using @Autoclosure technology; @autoclosure and no @Autoclosure constitute function overloading;