A function is a code self-contained block that performs a specific task. Given a function name identification, this identity can be used for "invoke" when performing its task.
Swift's unified functional syntax is flexible enough to express anything, be it a simple C-style function expression without even a parameter name, or a Objective-c language-style function that requires complex names for each local and external parameter. Parameter provides a default value to simplify the function invocation and to modify the passed variables when the function execution completes, by setting the input and output parameters.
Each function in Swift has a type, including the parameter type and return type of the function. You can easily use this type like any other type, which makes it easy to pass a function as a parameter to another function, or even return a function type from a function. Functions can also be written in other functions to encapsulate a nested function that is useful in a range of functions.
1, the function of the Declaration and call
When you define a function, you can define one or more different names, type values as input to the function (called parameters), and when the function completes, it returns the type of the output definition (called as its return type).
Each function has a function name that describes the task performed by the function. To use the function of a function, you "invoke" it by using its name, and it matches the parameter type of the function by its input value (called a parameter). The supplied parameters of a function must always be in the same order as the function argument list.
For example, the function called in the following example Greetingforperson, as it describes-it takes a person's name as input and returns a greeting to that person.
Copy Code code as follows:
Func SayHello (personname:string)-> String {
Let greeting = "Hello," + PersonName + "!"
return greeting
}
All of this information is summarized into the definition of the function and is prefixed with the Func keyword. The return type of the function you specified is returned with the arrow-> (a hyphen followed by a right angle bracket) and the name of the subsequent type.
The definition describes what the function is, what it expects to receive, and what the result is when it completes the return. This definition makes it easy for the function to allow you to invoke it in a clear and unambiguous way elsewhere in the code:
Copy Code code as follows:
println (SayHello ("Anna"))
Prints "Hello, anna!"
println (SayHello ("Brian"))
Prints "Hello, brian!"
Call the SayHello function, such as SayHello ("Anna"), by using a string type parameter value in parentheses. Because the function returns a string value, the SayHello can be wrapped in a println function call to print the string to see its return value, as shown in the figure above.
A new string constant named greeting is defined at the beginning of the SayHello function body and a simple greeting message is formed by adding the PersonName personal name to the set. Then the greeting function returns with the keyword return. The current value of the greeting is returned whenever the function completes when the greeting function is called.
You can call the SayHello function multiple times with different input values. The above example shows what happens if it takes "Anna" as an input value and "Brian" as the input value. The return of functions is a tailored greeting in each case.
To simplify the body of this function, combine the message creation and return statements in one line:
Copy Code code as follows:
Func SayHello (personname:string)-> String {
Return "Hello again," + PersonName + "!"
}
println (SayHello ("Anna"))
Prints "Hello Again, anna!"
2, function parameters and return values
The parameters and return values of functions in Swift are very flexible. You can define anything whether it's a simple function with an unnamed parameter or a complex function that has a rich parameter name and different parameter options.
Multiple input parameters
A function can have multiple input parameters, write them in parentheses within the function, and separate them with commas. The following function sets a half open interval for a start and end index to calculate how many elements in the range contain:
Copy Code code as follows:
Func halfopenrangelength (Start:int, end:int)-> Int {
Return End-start
}
println (Halfopenrangelength (1, 10))
Prints "9"
no parameter function
The function does not require an input parameter that must be defined. The following is a function that has no input parameters, and it always returns the same string message whenever it is invoked:
Copy Code code as follows:
Func SayHelloWorld ()-> String {
Return to "Hello, World"
}
println (SayHelloWorld ())
Prints "Hello, World"
The function's definition requires parentheses after the name of the function, even if it takes no arguments. The function name also follows a pair of empty parentheses when the function is invoked.
function with no return value
function also does not need to define a return type. Here is a version of the SayHello function called Wavegoodbye, which outputs its own string value instead of the function return:
Copy Code code as follows:
Func Saygoodbye (personname:string) {
println ("Goodbye, (personname)!")
}
Saygoodbye ("Dave")
Prints "Goodbye, dave!"
Because it does not need to return a value, the definition of the function does not include the return Arrows (–>) and the return type.
Tips
strictly speaking, the Saygoodbye feature does return a value even if there is no return value definition. function does not define return type but return
Returns a special value for a void return type. It is an almost empty tuple, in fact a tuple of 0 elements that can be written as ().
When a function is called, its return value is negligible:
Copy Code code as follows:
Func Printandcount (stringtoprint:string)-> Int {
println (Stringtoprint)
Return Countelements (Stringtoprint)
}
Func printwithoutcounting (stringtoprint:string) {
Printandcount (Stringtoprint)
}
Printandcount ("Hello, World")
Prints "Hello, World" and returns a value of 12
Printwithoutcounting ("Hello, World")
Prints "Hello, world" but does is not return a value
The first function Printandcount, prints a string, and then returns the number of characters with the int type. The second function, printwithoutcounting, calls the first function, but ignores its return value. When the second function is invoked, the string message is printed back by the first function and goes without using its return value.
Tips
The return value can be ignored, but for a function, its return value is bound to return even if it is not used. At the bottom of the function body
When returning a function that is incompatible with a defined return type, attempting to do so will result in a compile-time error.
Multiple return value function
You can use a tuple type as the return type of a function to return a composite with multiple values as the return value.
The following example defines a named count function that calculates the number of vowels, consonants, and characters that are used in standard American English in a string:
Copy Code code as follows:
Func count (string:string)-> (Vowels:int, Consonants:int, Others:int) {
var vowels = 0, consonants = 0, others = 0
For character in string {
Switch String (character). lowercasestring {
Case "A", "E", "I", "O", "U":
++vowels
Case "B", "C", "D", "F", "G", "H", "J", "K", "L", "M",
"N", "P", "Q", "R", "s", "T", "V", "w", "X", "Y", "Z":
++consonants
Default
++others
}
}
return (vowels, consonants, others)
}
You can use this count function to count the characters of any string and retrieve the tuple three specified int values for the total number of statistics:
Copy Code code as follows:
Let total = count ("Some arbitrary string!")
println ("\ (total.vowels) vowels and \ (total.consonants) consonants")
Prints "6 vowels and consonants"
It is important to note that at this point the members of the tuple do not need to be named in the tuple returned by the function because their name has been specified as part of the return type of the function.
3, function parameter name
All of the above functions define the parameter name for the parameter:
Copy Code code as follows:
Func someFunction (parametername:int) {
function body goes here, and can use ParameterName
To refer to the argument value of that parameter
}
However, these parameter names can only be used within the body of the function itself, and cannot be used when calling a function. The parameter names of these types are referred to as local parameters because they apply only to the body of the function.
The name of the external parameter
Sometimes it is useful to call a function to name each parameter to indicate the purpose of each parameter you pass to the function.
If you want the user function to call your function with the parameter name, in addition to setting the local parameter name, define the external parameter name for each parameter. You write an external parameter name separated by a space before the name of the local parameter that it supports:
Copy Code code as follows:
Func someFunction (Externalparametername localparametername:int) {
function body goes here, and can use Localparametername
To refer to the argument value of that parameter
}
Attention
If you provide an external parameter name for a parameter, the external name must always be used when calling the function.
As an example, consider the following function, which connects two strings by inserting a third "joiner" string between them:
Copy Code code as follows:
Func Join (s1:string, s2:string, joiner:string)-> String {
return s1 + joiner + s2
}
When you call this function, the purpose of the three strings you pass to the function is not very clear:
Copy Code code as follows:
Join ("Hello", "World", ",")
Returns "Hello, World"
For the purpose of these string values to be clearer, define an external parameter name for each join function parameter:
Copy Code code as follows:
Func Join (String s1:string, toString s2:string, Withjoiner joiner:string)
-> String {
return s1 + joiner + s2
}
In this version of the Join function, the first argument has an external name string and a local name S1, the second argument has an external name ToString and a local name S2, and the third parameter has an external name Withjoiner and a local name joiner.
You can now call the function clearly and explicitly by using these external parameter names:
Copy Code code as follows:
Join (string: "Hello", toString: "World", Withjoiner: ",")
Returns "Hello, World"
Using an external parameter name makes the second version of the Join function more expressive, the user is accustomed to using the Sentence-like method, and provides a readable, intent-specific function body.
Attention
Consider the idea of using an external parameter name to not know what your function parameters are for the first time someone reads your code.
But when a function is called, if the purpose of each argument is clear and unambiguous, you do not need to specify an external parameter name.
External parameter name shorthand
If you want to provide an external parameter name for a function parameter, but the local parameter name already uses an appropriate name, you do not need to write the same two-time name for the parameter. Instead, write the first name and prefix the name with a hash symbol (#). This tells Swift to use the name as both a local parameter name and an external parameter name.
This example defines a function named Containscharacter that defines the external parameter names of two parameters and by placing a hash mark before their local parameter name:
Copy Code code as follows:
Func Containscharacter (#string: String, #characterToFind: Character)-> Bool {
For character in string {
if character = = Charactertofind {
return True
}
}
return False
}
This function selects the parameter name is clear, the function body is extremely readable, causes this function to be invoked does not have the ambiguity:
Copy Code code as follows:
Let Containsavee = Containscharacter (string: "Aardvark", Charactertofind: "V")
Containsavee equals True, because "aardvark" contains a "V"
Default values for parameters
You can set a default value for any parameter as part of the definition of a function. If the default value is already defined, the pass value of the parameter can be omitted when the function is invoked.
Attention
The parameters that use the default values are placed at the end of the function's argument list. This ensures that the non-default arguments for all calling functions use the same smoothing
Sequence, and explicitly represents the same function call in each case.
Here is a version of the early join function and set the default value for the parameter joiner:
Copy Code code as follows:
Func Join (String s1:string, ToString s2:string,
Withjoiner joiner:string = "")-> String {
return s1 + joiner + s2
}
provided to joiner a string value when the Join function is invoked, the string is used to concatenate two strings, as before:
Copy Code code as follows:
Join (string: "Hello", toString: "World", Withjoiner: "-")
Returns "Hello-world"
However, the default value of a single space ("") is used when a function is invoked to provide a joiner without a value:
Copy Code code as follows:
Join (string: "Hello", toString: "World")
Returns "Hello World"
External name parameter with default value
In most cases, it is useful to provide a name for all parameters with an external parameter with a default value (therefore required). This will make sure that when the function is invoked the value provided by the parameter must have a definite purpose.
To make this process easier, when you do not provide an external name yourself, Swift automatically defines the default parameter external name for all parameters. The automatic external name is the same as the local name, as if you wrote a hash symbol before the local name in your code.
Here is a version of the early join function that does not provide an external name for any arguments, but still provides the default value for the Joiner parameter:
Copy Code code as follows:
Func Join (s1:string, s2:string, joiner:string = "")-> String {
return s1 + joiner + s2
}
In this case, Swift automatically provides an external parameter name for a parameter that has a default value. When calling a function, you must provide an external name for the purpose of making the argument unambiguous and unambiguous:
Copy Code code as follows:
Join ("Hello", "World", Joiner: "-")
Returns "Hello-world"
Attention
You can choose to do this by writing an underscore (_), rather than an explicit definition of the external parameter name. and
An external name parameter with a default value, if appropriate, is always used preferentially.
Variable parameters
A parameter of a variable parameter accepts 0 or more values of the specified type. When a function is invoked, you can use a parameter of a variable parameter to specify that the parameter can pass a different number of input values. When you write parameters for a variable parameter, you need the type name of the parameter followed by the dot character (...). )。
When passing the value of a parameter of a variable parameter, the function body is present in the form of an array that provides the appropriate type. For example, the name of a variable parameter is numbers and the type is double ... A constant array named numbers type double[in the body of the function.
The following example calculates the arithmetic average (also known as the average) of a number of any length:
Copy Code code as follows:
Func Arithmeticmean (numbers:double ...)-> Double {
var total:double = 0
For number in numbers {
Total + = number
}
Return total/double (Numbers.count)
}
Arithmeticmean (1, 2, 3, 4, 5)
Returns 3.0, which is the arithmetic mean to these five numbers
Arithmeticmean (3, 8, 19)
Returns 10.0, which is the arithmetic mean to these three numbers
Attention
A function can have at most one parameter of a variable parameter, and it must appear at the end of the argument list to avoid multiple parameter letters
Ambiguity occurs when a number of calls occur.
If a function has one or more parameters that use default values, and also has variable parameters, place the variable parameters in the list's
After the parameters of all the default values at the end.
Constant parameters and variable parameters
The default values for function parameters are constants. Attempting to change the value of a function parameter causes a compile-time error within the function body. This means that you cannot incorrectly change the value of the parameter.
However, it is sometimes useful to have a variable copy of the value of a function with a parameter. Instead of defining a new variable within a function, you can specify one or more parameters as variable arguments. A variable argument can be a variable instead of a constant and provide a copy of the value of the newly modified parameter in the function.
Define variable parameters with keyword var before the parameter name:
Copy Code code as follows:
Func AlignRight (Var string:string, Count:int, Pad:character)-> string {
Let Amounttopad = count-countelements (String)
For _ in 1...amountToPad {
String = Pad + string
}
return string
}
Let originalstring = "Hello"
Let paddedstring = AlignRight (originalstring, 10, "-")
PaddedString is equal to "-----Hello"
Originalstring is still equal to "hello"
This example defines a new function called AlignRight, which is aligned with an input string to a longer output string. Fills the specified characters in the left space. In the example, the string "Hello" is converted to the string "-–hello".
The AlignRight function defines the string of input parameters as a variable parameter. This means that the string can now be used as a local variable, initialized with the passed-in string value, and can be manipulated in the function body.
The function first finds out how many characters need to be added to the left so that the string is right-aligned in the entire string. This value is stored in the local constant amounttopad. The function then copies the Amounttopad character of the fill character to the left of the existing string and returns the result. The entire process uses string variable arguments for string manipulation.
Attention
The change of a variable parameter does not exceed each call function, so it is not visible to the external function body. Variable arguments can only exist in function calls
Life cycle.
Input-Output parameters
Variable parameters, as described above, can only be changed within the function itself. If you want to have a function that modifies the value of a parameter, and you want these changes to persist after the function call is over, you can define the input-output parameters instead.
The input-output parameter is indicated by adding the InOut keyword at the beginning of its parameter definition. An input-output parameter has a value passed to the function, modified by the function, and returned from the function to replace the original value.
4. Function type
Each function has a specific type, including parameter types and return value types, such as:
Copy Code code as follows:
Func addtwoints (A:int, b:int)-> Int {
Return a + b
}
Func multiplytwoints (A:int, b:int)-> Int {
return a * b
}
This example defines two simple mathematical functions addtwoints and multiplytwoints. Each function accepts two int parameters, returns an int value, performs the corresponding mathematical operation, and then returns the result
The types of these two functions are (int, int)->int can be interpreted as:
This function type has two int parameters and returns a value of type int
The following example is a function that takes no arguments and returns a value:
Copy Code code as follows:
Func Printhelloworld () {
println ("Hello, World")
}
The type of this function is ()-> (), or the function has no arguments and returns void. The function does not explicitly specify a return type, the default is void, which is equivalent to an empty tuple in Swift, which is recorded as ().
Working with Function types
In Swift you can use function types like any other type. For example, you can define a constant or variable as a function type, and specify the appropriate function for the variable:
Copy Code code as follows:
var mathfunction: (int, int)-> Int = addtwoints
Can be read as follows:
"Defines a mathfunction variable whose type is ' a function that accepts two int values and returns an int value." ' Set this new variable to refer to the function called the addtwoints function. ”
The Mathfunction function has the same type of variable as the addtwoints function, so this assignment can be checked by Swift's type.
Now you can call the specified function name mathfunction:
Copy Code code as follows:
println ("Result: \ (Mathfunction (2, 3))")
Prints "Result:5"
The same type of matching for different functions can be assigned to the same variable, and the same is true for non functional types:
Copy Code code as follows:
Mathfunction = multiplytwoints
println ("Result: \ (Mathfunction (2, 3))")
Prints "Result:6"
As with any other type, you can quickly define it as a function type when you assign a function to a constant or variable:
Copy Code code as follows:
Let anothermathfunction = addtwoints
Anothermathfunction is inferred to be of type (int, int)-> int
parameter of function type
You can use a function type, such as (int, int)->int as the parameter type of another function. This allows you to reserve the implementation of some aspects of a function that are provided by the caller when calling the function.
The following is an example of the result of printing the above mathematical function:
Copy Code code as follows:
Func Printmathresult (mathfunction: (int, int)-> Int, A:int, B:int) {
println ("Result: \ (Mathfunction (A, B))")
}
Printmathresult (Addtwoints, 3, 5)
Prints "Result:8"
This example defines a function called Printmathresult, which has three parameters. The first parameter is named Mathfunction, and the type is (int, int)->int. You can pass in any function type that meets the criteria as the first parameter of this function. The second and third parameters, A, b are all int types. is used to provide two input values for mathematical functions.
When Printmathresult is invoked, it passes the Addtwoint function, and the integer values 3 and 5. It uses 3 and 5, calls the Addtwoint function, and prints the result of the function running 8.
The role of Printmathresult is to call an appropriate type of mathematical function and print the corresponding result. That's what the implementation of the function is not important, you just give the right type to match on the line. This enables Printmathresult to transform the functionality of the function in a way that is safe for the caller type.
return value of function type
You can use one function type as the return type of another function. The returned function (->), which is your return arrow, immediately writes a complete function type to do so.
The following example defines two simple functions, namely Stepforward and Stepbackward. The Stepforward function returns an input value of 1, whereas the Stepbackward function returns the input value from minus 1. Both of these functions have an identical type (int)-> int:
Copy Code code as follows:
Func Stepforward (input:int)-> Int {
return input + 1
}
Func Stepbackward (input:int)-> Int {
Return input-1
}
Here is a choosestepfunction function whose return type is "function type (int)-> int". Choosestepfunction returns a Stepbackward or Stepforward function type based on a Boolean parameter:
Copy Code code as follows:
Func choosestepfunction (Backwards:bool)-> (int)-> int {
return backwards? Stepbackward:stepforward
}
You can now use Choosestepfunction to select a function, perhaps by adding a function or another:
Copy Code code as follows:
var currentvalue = 3
Let Movenearertozero = choosestepfunction (CurrentValue > 0)
Movenearertozero now refers to the Stepbackward () function
The example above can be used to determine whether the positive and negative decisions of the steps need to be moved so that the CurrentValue variable approaches 0. The CurrentValue initial value is 3, which means that the current value >0, returns the True,choosestepfunction return Stepbackward function. The reference to the return function is stored in a called Movenearertozero constant.
Now that the Movenearertozero performs the right function, it can be used to count to 0:
Copy Code code as follows:
println ("Counting to Zero:")
Counting to zero:
While CurrentValue!= 0 {
println ("\ (CurrentValue) ... ")
CurrentValue = Movenearertozero (CurrentValue)
}
println ("zero!")
3..
2..
1..
Zero!
5. Nested functions
So far all the functions you have encountered in this chapter are global functions and are defined globally. In fact, you can also define functions in other functions, called nested functions.
Nested functions are hidden by default to the outside world, but they can still invoke and use their internal functions. An intrinsic function can also return a nested function, allowing it to be used within another scope within a nested function.
You can rewrite the choosestepfunction example above to use and return nested functions:
Copy Code code as follows:
Func choosestepfunction (Backwards:bool)-> (int)-> int {
Func Stepforward (input:int)-> Int {return input + 1}
Func Stepbackward (input:int)-> Int {return input-1}
return backwards? Stepbackward:stepforward
}
var CurrentValue =-4
Let Movenearertozero = choosestepfunction (CurrentValue > 0)
Movenearertozero now refers to the nested Stepforward () function
While CurrentValue!= 0 {
println ("\ (CurrentValue) ... ")
CurrentValue = Movenearertozero (CurrentValue)
}
println ("zero!")
-4 ...
-3 ...
-2 ...
-1 ...
Zero!