First, the introduction
A function is a code snippet that has a specific function, and a function is used when a specific name is invoked. Swift provides a very flexible way to create and invoke functions. In fact, in swift, each function is a type, which is determined by parameters and return values. A big difference between swift and objective-c is that functions in Swift can be nested.
And the closure in Swift is a code block with a certain function, which is very similar to the chunk syntax in Objective-c. The closure syntax style in Swift is very concise, and its function and functions are similar.
Creation and invocation of functions
Functions are defined by function names, parameters, and return values, and parameters and return values determine the type of a function, which is invoked using the function name when calling a function, as shown in the following example:
Pass in a name to print and return it to
func printname (name:string)-> String {
print (name) return
name
}
//Call to function
printname ("HS")
You can also create a function that has no parameters:
Func onepusetwo ()->int {
return 1+2
}
onepusetwo ()
can also create a function that does not have a value returned:
func SayHello () {
print ("Hello")
}
SayHello ()
The function types described above are common, and for functions that return values are very difficult to deal with in objective-c, developers usually use a dictionary, array, and so on, or simply using the block callback, in Swift, you can use a tuple as the return value of the function, examples are as follows:
Func tuples ()-> (int,string) {return
(1, "1")
}
tuples ()
It can also be a function that returns the value of a optional type, and supports the return of nil, as shown in the following example:
Func func1 (param:int)->int? {
Guard (param>0) else{return
nil
} return
param
}
func1 (0)
func1 (1)
Before the parameter name of a function, the developer can also add a parameter name to it as an external parameter name, as shown in the following example:
Func func1 (Count Param:int, Count2 param2:int)->int? {/
/internal still use Param
Guard (param>0) else{return
nil} return
param
}
/ External calls use Count
func1 (count:0,count2:0)
func1 (count:1,count2:1)
In fact, the list of parameters in the SWIFT function has the feature that, in addition to the first argument, the subsequent arguments are added by default to an external name that is the same as the internal name, and if the developer does not want to use the external name, use the _ symbol setting, as shown in the following example:
Func Func2 (param:int,param2:int,param3:int) {
}
//has an external name
func2 (0, param2:0, param3:0)
func func3 ( Param:int,_ param2:int,_ param3:int) {
}
//No external name
func3 (0, 0, 0)
Swift also supports developers to create a default value for the parameters of a function, and if a parameter of a function has a default value set, the developer can omit this parameter when invoked, as shown in the following example:
Func Func4 (param:int=1,param2:int=2,param3:int) {
print (PARAM,PARAM2,PARAM3)
}
Func4 (3,param3:3)
There is also a situation that is handled in objective-c, and for functions with indefinite parameters, as described in the previous section, Objective-c typically uses the list pointer to do so, and it is easy to write such a function in Swift, as the following example:
Func Func5 (Param:int ...) {for
index in param {
print (index)
}
}
Func5 (1,2,3,4)
In swift, the parameter defaults to constants, and in a function it is not possible to modify external incoming parameters, and if there is a requirement, you need to declare the parameters as InOut types, as shown in the following example:
Func Func6 (inout param:int) {
param = ten
}
var count = 1
//actually passed in the parameter address
Func6 (&count)
Print (count)
Three, function type
A function is a special type of data, and each function is a data type, as the following example:
Func Func7 (a:int,_ b:int)->int{return
a+b
}
var addfunc: (int,int)->int = Func7 addfunc
(1,2)
A function can also pass in another function as a parameter, which is very similar to the block syntax in Objective-c, as shown in the following example:
Func Func7 (a:int,_ b:int)->int{return
a+b
}
var addfunc: (int,int)->int = Func7 addfunc
(1,2)
func Func8 (param:int,param2:int,param3: (int,int)->int)-> Int {return
param3 (param,param2)
}
//Incoming function
Func8 (1, Param2:2, Param3:addfunc)
//Closure mode
FUNC8 (2, Param2:2, param3:{(a:int,b:int)- > Int in return
a*b
})
A human function can also serve as a return value for another function, as shown in the following example:
Func func9 ()-> (Int)->int{
//swift Support nested functions
func tmp (a:int)->int{return
a*a
}
return tmp
}
var myFunc = func9 ()
MyFunc (3)
Four, from a system function to look at the closure
The SWIFT standard function library provides a sort sort function that, for an array of already element types, calls the sort function to reorder and return the new sorted array. This sort function can receive a closed package with a return value of type bool to determine whether the first element is in front of the second element. The code example is as follows:
var array = [3,21,5,2,64]
func func1 (param1:int,param2:int)-> Bool {return
param1>param2
}
//
//array = [64,21,5,3,2]
array = array.sort (func1)
//via closure by way of passing in function
//array = [2,3,5,21,64]
Array = Array.Sort ({(param:int,param2:int)->bool in return
param<param2
})
One notable feature of the Swift language is simplicity, which can be inferred by context. General development can omit type writing, which is also a thought in swift language design, because closures are passed into functions as parameters of functions because the type of function argument is OK, So the type of closure can be inferred by the compiler, and the developer can omit the parameter type and return value of the closure, and the above code can be abbreviated as follows:
Omit the parameter type and return value of the closure
array = Array.Sort ({(P1,P2) in return P1>P2})
In fact, if the function body in the closure has only one line of code, the return keyword can also be omitted, and the value of this line of code is implicitly returned, as follows:
Array = Array.Sort ({(P1,P2) in p1>p2})
See the above expression, is not a little shock, the closure of the expression can be abbreviated to this! However, you're still underestimating the swift development team, and the grammar rules behind it will give you an idea of the ultimate simplicity. You can see that the above code implementation still has 3 parts: parameters and return values, closures keyword, function body. The parameter and return value are the argument list, P1,P2, although the parameter type and the return value type are omitted, this part of the module is still in, the closure keyword is in, it is used to indicate that the following will be the closure of the function body, P1>P2 is the function body, except here omitted return keyword. Since both the parameter type and the return value type compiler can be inferred from the closure, the number of parameters editor can also be inferred, therefore, the argument list is actually redundant, the closure will automatically generate some parameter names, and the actual number of parameters to correspond, such as the top of the sort function in the closure has two parameters , the system will automatically generate $ and the two parameter names, developers can use directly, because the argument list will be omitted, then also no longer need the closure keyword in to separate the parameter list and function body, at this time, the closure of the writing actually becomes the following appearance:
Array = Array.Sort ({$0<$1})
You did not read the wrong, plus about the curly braces, a total of 7 characters, completed a sorting algorithm. Apart from Swift, I don't know if there is a second language that can be done. Throw the opening and closing package not to mention, Swift also has a syntax that defines the type of operator methods, such as string types that can be compared through =,<,>, which are actually implemented in the string class, and in a sense an operator is similar to a function, Well, the method that needs to be passed in the sort function actually requires only one operator for some types, as the following example:
This time you can really be shocked to finish sorting the new algorithm requires only one character, one character at a time.
More features of closures in Swift
One interesting feature of the closures in Swift is that first, the closure is passed into another function as a parameter, so the usual way of writing is to write the braces of the closure in parentheses in the function's argument list, and if there is a lot of code in the closure, then it becomes less clear in the code structure, in order to solve this problem, Swift says this: If the closure parameter is the last parameter of the function, the developer can pull it out of parentheses and implement the closure code at the end of the function, as shown in the following example:
Closure End
Func func2 (param1:int,param2: ()->void)->void{
param2 ()
print ("Func2 function invoked")
}
Func2 (0) {
print (contents in closure)
}
If there is only one parameter in a function, and the parameter is a closure, then the developer uses the end of the closure to simply omit the parentheses from the function's argument list, as shown in the following example:
Func func3 (param: ()->void)->void{
param ()
print (called Func3 function)
}
func3{
print (" Contents in closure ")
}
There is also the concept of a closure escape in Swift, this is well understood, when the closure is passed into the function as a parameter, if the closure is only used in the function, the developer can declare the closure as a non escaping, telling the system that when the function is finished, the closure's declaration cycle will also end. The advantage of this is that you can improve code performance by using the @noescape keyword for a closure statement that is not a runaway type, as shown in the following example:
Func func3 (@noescape param: ()->void)->void{
param ()
print (called Func3 function)
}
func3{
print ("contents in Closure")
}
Escape closures are often used for asynchronous operations, such as the closure that handles a network request asynchronously, and the closure's declaration cycle only ends when the request is finished. Non-escaping closures also have an interesting feature in which self can be omitted if it is necessary to use the Self keyword.
Closures can also be automatically generated, this closure is called automatic closure, automatic closure can automatically encapsulate the expression into a closure, the developer does not need to write the closure of the curly brace format, automatic closure does not receive parameters, the return value is the value of the expression. Examples are as follows:
Auto-closure Demo
var list = [1,2,3,4,5,6]
///Create an explicit closure let
closures = {
List.removefirst ()
list.append (7)
}
print [1,2,3,4,5,6] print
(list)/
/execute closure
closures ()
//will print [2,3,4,5,6,7] print
(list)
Func Func4 (Closure: ()->void)-> Void {
//execute an explicit closure
closures ()
}
func Func5 (@autoclosure Auto :()->void)-> Void {
//execute auto Closure
auto ()
}//
/Explicit closure requires curly braces
Func4 (closures)
//will print [ 3,4,5,6,7,7]
print (list)
//auto-Generate closure
Func5 (List.append (8))
//will print [3,4,5,6,7,7,8]
Print (list)
Automatic closure defaults to escape, if you want to use the escape closure, you need to manually declare, as follows:
Func Func5 (@autoclosure (escaping) Auto: ()->void)-> Void {
//execute auto Closure Auto
()
}