Swift Learning notes-functions and closures

Source: Internet
Author: User

Import Foundation

1. Definition and invocation of functions
Prefixed with Func, return arrow-----Returns type of function
Func SayHello (name:string), String {
Let greeting = "Hello" + name + "!"
return greeting
}

println (SayHello ("Anna"))

1.1 Parameters and return values for functions
Functions can have multiple input parameters, written in parentheses, separated by commas
Func Minusresult (Start:int, end:int), int{
Return End-start
}

println (Minusresult (1, 10))

1.2 No parameter function
Func SayHelloWorld (), String {
Return "Hello World"
}
println (SayHelloWorld ())


1.3 No return value function
/*
Strictly speaking, although no return value is defined, the Saygoodbye function returns a value.
A function that does not define a return type returns a special value called Void. It is actually an empty tuple (tuple), without any elements that can be written ().
*/
Func Saygoodbye (name:string) {
println ("Goodbye, \ (name)")
}
println (Saygoodbye ("Dave"))


1.4 Multiple return value functions
You can use a tuple (tuple) type to return multiple values from a function as a composite value
Func count (string:string)--(Vs:int, Cs:int, Os: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)
}
Let total = count ("Some arbitrary string!")
println ("\ (Total.vs) vowels and \ (total.cs) consonants")


2 function Parameter name
2.1 External parameter names

Demo: Concatenate two characters together to demonstrate the benefits of using external parameters
/*
Do not use external parameters
Func Join (s1:string, s2:string, joiner:string), String {
return s1 + joiner + s2
}
println (Join ("Hello", "World", ","))//The use of these three strings is not very clear
*/

/*
Using external parameter names
To make the use of these strings more obvious, we add external parameter names to the Join function
Func Join (String s1:string, toString s2:string, Withjoiner joiner:string), string {
return s1 + joiner + s2
}
The use of external parameter names is more expressive, more fluent, but also maintains that the function body is readable and has a clear intention
println (Join (string: "Hello", toString: "World", Withjoiner: ","))
*/


2.2 Shorthand External parameter name
If you need to provide an external parameter name, but the local parameter name is already defined, then you do not need to write the parameter names two times. Instead, write only the parameter name once and prefix it with the pound sign (#). This tells Swift to use this parameter name as a local and external parameter name.
Func Containscharacter (#string: String, #characterToFind: Character), Bool {
For character in string {
if character = = Charactertofind {
return True
}
}

return False
}

This defines the parameter name, making the function body more readable, legible, and can be called in an unambiguous manner.
Let Containsavee = Containscharacter (string: "Qwertyuiop", Charactertofind: "Y")
println (Containsavee)


2.3 Default parameter values
You can define default values for each parameter in the body of the function. When the default value is defined, this parameter can be omitted when calling this function
Func Join (String s1:string, toString s2:string, Withjoiner joiner:string = ","), string {
return s1 + joiner + s2
}
Let str1 = Join (string: "Hello", toString: "World", Withjoiner: "-")//Specify the third parameter
println (STR1)

Let str2 = Join (string: "Hello", toString: "World")//Do not specify a third parameter, the third parameter will use the default value
println (STR2)

2.4 External parameter name for the default value parameter
When you do not provide an external parameter name for a parameter with a default value, Swift automatically provides an external name. The external parameter name is the same as the local name, as if you had written a pound sign (#) in front of the local parameter name.
Func Join (s1:string, s2:string, joiner:string = ""), String {
return s1 + joiner + s2
}
Let STR3 = join ("Hello", "World", Joiner: "-")
println (STR3)


3. Variable parameters
The value passed in the variable parameter is treated as an array of this type in the body of the function. For example, a Double named numbers ... Type variable parameter, which can be used as an array constant in the function body as a double[] type called numbers.
A function can have a maximum of one variable parameter
The variable parameter must be placed in the last position in the parameter table
Func Aritheticmean (numbers:double ...), Double {
var total:double = 0
For number in numbers {
Total + = number
}
Return total/double (Numbers.count)
}
println (Aritheticmean (1.2, 3.5, 4.6))
println (Aritheticmean (1.2, 3.5, 4.6, 9.0, 10.0))

4 constant parameters and variable parameters
function parameters are constants by default. Sometimes, however, it is useful if the parameters passed in the function can be modified. You can avoid defining new variables in the function by specifying one or more arguments as variable arguments. The variable parameter is not a constant, and you can use it as a new modifiable copy in the function.
Define variable parameters by adding the keyword var before the parameter name
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, "-")
println ("originalstring:" + originalstring)
println ("paddedstring:" + paddedstring)


5 Input and OUTPUT parameters
Variable parameters, as described above, can only be changed within the function body. If you want a function that modifies the value of a parameter, and you want these modifications to persist after the function call ends, you should define the parameter as an input-output parameter (in-out Parameters).

Define an input/output parameter, and precede the parameter with the InOut keyword
Input and output parameters cannot have default values, and mutable parameters cannot be marked with inout. If you mark a parameter with inout, this parameter cannot be marked by Var or let.
Func swaptwoints (inout a:int, inout b:int) {
Let temp = a
A = b
b = Temp
}

Only one variable can be passed as an input-output parameter
var someint = 3
var anotherint = 7
When an incoming parameter is used as an input and output parameter, it needs to be preceded by a &, indicating that the value can be modified by the function
Swaptwoints (&someint, &anotherint)
println ("Someint is now \ (Someint), and Anotherint are now \ (anotherint)")


6. Function type (is a data type, like a C-language function pointer, OC language block)
In three steps: 1. Define functions; 2. Declaring a function type variable or constant; 3. Assigning a value to a function type variable
1. Defining functions
Func addtwoints (A:int, b:int), Int {
Return a + b
}

Func sum (a:int, b:int), Int {
Return A-B
}

Func Printhelloworld ()
{
println ("Hello, World")
}

/*
2, declare a variable called mathfunction, the type is ' a function with two int parameter and return the value of an int type '
var mathfunction: (int, int), int

3. Assigning a value to a function type variable
Mathfunction = addtwoints


Since it is a variable, we can assign it to mathfunction again.
Mathfunction = Sum
*/

/*
2 3-Step Merge
var mathfunction: (int, int), int = sum
*/

Type derivation, which allows Swift to speculate on the type of mathfunction
var mathfunction = sum
Mathfunction = printhelloworld//error, type mismatch


4. Use
println ("Result: \ (Mathfunction (2, 3)")

Swift calls the C function
DESC1 ()

Swift calls OC
var funcclass = Funcblock ()//Get OC Class object
FUNCCLASS.DESC2 ()


6.1 function type as parameter type
Func Printmathresult (mathfun: (int, int), int, a:int, b:int) {
println ("Result: \ (Mathfun (A, b)")
}
Printmathresult (Addtwoints, 4, 7)


/*
6.2 Function type as return type
Func Stepforward (input:int), Int {
return input + 1
}
Func Stepbackward (input:int), Int {
println ("Stepbackward")
Return input-1
}

OK, is there any dizzy??? When you're dizzy, take a break and read what you just said.
Func choosestepfunction (Backwards:bool)-(int)-int {
return backwards? Stepbackward:stepforward//Return function type
}
var currentvalue = 3
Let Movenearertozero = choosestepfunction (CurrentValue > 0)
Let Movenearertozero: (int), int = Choosestepfunction (true)//prototype
Movenearertozero = Stepbackward
println ("Movenearertozero:\ (Movenearertozero)")//movenearertozero point to Stepbackward

println ("Result:\ (Movenearertozero (10))")
*/

Nested functions
Func choosestepfunction (Backwards:bool)-(int)-int {
Func Stepforward (input:int), Int {
return input + 1
}
Func Stepbackward (input:int), Int {
println ("Stepbackward")
Return input-1
}
return backwards? Stepbackward:stepforward//Return function type
}
var CurrentValue =-4
Let Movenearertozero = choosestepfunction (CurrentValue > 0)
println ("Nested functions: \ (Movenearertozero (10))")


8. Closures
8.1 Closed-Packet expressions

Let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]


Do not use closures
Func Backwards (s1:string, s2:string), Bool {
return s1 > S2
}
The Swift Standard library provides a sort function that sorts the values in the known type array based on the closure function you provide for sorting based on the output type.
var reversed = sort (names, backwards)
println (Reversed)


Using closures
The function body part of the closure is introduced by the keyword in. The keyword indicates that the closure parameter and the return value type definition have been completed and the closure function body is about to begin.
Reversed = sort (names, {(s1:string, s2:string), Bool in
return s1 > S2
})

Infer types based on context
Reversed = sort (names, {s1, S2 in return s1 > s2})


8.2 Single-expression closed Baoyin return
If the closure body has only one expression, the return keyword can be omitted
Reversed = sort (names, {s1, s2 in S1 > s2})

8.3 parameter name abbreviation
$ $ and $ $ represent the parameters of the first and second string types in a closure.
Reversed = sort (names, {$ > $})

8.4 operator functions
Swift's string type defines the strings implementation for the greater-than sign (>)
Reversed = sort (names, >)


8.5 Trailing closures
If you need to pass a long closure expression (so that it cannot be written on a single line) as the last argument to the function, you can use a trailing closure to enhance the readability of the function. A trailing closure is a closure expression that is written after the function brackets, and the function supports calling it as the last argument.
Reversed = sort (names) {$ > $}

println (Reversed)

8.6 Capturing values
Func makeincrementor (Forincrement amount:int), ()->int {
var runningtotal = 0

The Incrementor function did not get any arguments, but the runningtotal and amount variables were accessed within the function body. This is because it is implemented by capturing runningtotal and amount variables that already exist in the function body that contains it.
Func incrementor (), Int {
RunningTotal + = Amount
Return RunningTotal
}

Return Incrementor
}
Let Incrementbyten = Makeincrementor (forincrement:10)

Because the value of RunningTotal is modified every time the function is called, Incrementor captures the reference to the current runningtotal variable instead of just copying the initial value of the variable. Capturing a reference guarantees that the makeincrementor will not disappear at the end of the session, and that the next time the Incrementor function is executed, runningtotal can continue to increase
println (Incrementbyten ())//10
println (Incrementbyten ())//20
println (Incrementbyten ())//30


Let Incrementbyseven = Makeincrementor (forincrement:7)
println (Incrementbyseven ())//7
println (Incrementbyten ())//40


8.7 Closures are reference types
In the above example, Incrementbyseven and Incrementbyten are constants, but the closures that these constants point to can still increase the value of the variable they capture. This is because both the function and the closure are reference types.

If you assign a closure to two different constants/variables, two values will point to the same closure, pointing to the Incrementor
Let Alsoincrementbyten = Incrementbyten
println (Alsoincrementbyten ())//50

Swift Learning notes-functions and closures

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.