Swift Learning note fifth (closures and enumerations)

Source: Internet
Author: User
Tags closure constant memory usage sort
Closed Package

Closures: self-contained blocks of code that can be passed and used in code, closures can capture and store references to any constants and variables in the context in which they are located this is called closures and wraps these constants and variables, commonly known as closures

Three forms of closures
1. The global function is a name but does not capture any worthy closures
2. A nested function is a named and can be captured within its enclosing function is worth a closure
3. The closure expression is an example of an anonymous closure sorted function written in lightweight syntax that can capture the variables and constants of its context

Public func sorted (by Areinincreasingorder: (element, Element), Bool), [element]

Func someFunction (Externalparametername localparametername:int) {
function body goes here, and can use Localparametername
To refer to the argument value for that parameter
}
If you want the user of a function to provide a parameter name when calling a function, you need to define an external parameter name in addition to the local parameter name for each parameter. The external parameter name is written before the local parameter name, separated by a space.

1. As you can see, by is actually exposed to the external parameter name, and Areinincreasingorder is the internal variable name
2. Parameters: Closure function The closure function needs to pass in two values that are the same as the array type and return a Boolean type value to tell the sorted function whether the first parameter passed in after the sort end is preceded or followed by the second argument. If the first parameter value appears before the second parameter value, the sort closure function needs to return true and vice versa to return False
3. Look at the most common invocation

Let names = ["AAAA", "CCC", "FFF", "GGGGG", "tttt", "HHHH"]

func sortclosurefunc (s1:string,s2:string)->bool{
    return s1 > S2
}

var results = names.sorted (By:sortclosurefunc)
closure syntax and usage
    the code above {(parameters)
-returentype in statement}
can be simplified to the following
results = names.sorted (by: {(S1: String, s2:string), Bool
    in return s1 > S2
})
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. So the line is done
results = names.sorted (by: {(s1:string, s2:string)-Bool in return s1 > s2})
closure syntax based on context inference
In fact, in any case, when a closure constructed with an inline closure expression is passed as a parameter to a function, the parameter and return value type of the closure can be inferred, which means that you hardly need to construct any inline closures
results = names.sorted (by: { S1,s2 in
    return s1 > S2
})
The hidden return of the closed-packet syntax
Single expression can hide the result of a single line return by hiding the return keyword
results = names.sorted (by: {s1,s2 in S1 > s2})
Print (results)
parameter name abbreviation
Swift automatically provides parameter name abbreviations for inline functions, and you can call the closure parameters directly from $0,$1,$2.
results = names.sorted (by: {$ <})
print (results)
operator Functions
There is actually a shorter way to write the closure expression in the example above. The string type of Swift defines the implementation of strings for the greater-than sign (>), which accepts two string arguments as a function and returns a value of type bool
results = names.sorted (by: >)
Print (results)
trailing closures (system default)

If you need to pass a long closure expression as the last argument to a function, you can use a trailing closure to enhance the readability of the function.
If the function needs only one parameter of the closure expression, you can even omit () when you use the trailing closure

Trailing closure Closure Training
func somefunctionclosure (Closure: ()) {
    //function Body
}

//old-fashioned notation
Somefunctionclosure (closure: {})

//Trailing
somefunctionclosure () {}


//If the function needs only one parameter of the closure expression, when you use a trailing closure, you can even () omitted.  recommended notation
somefunctionclosure {

}
so the demo above can be simplified to
results = names.sorted{$0<$1}
print ( Results
Enumeration

General wording

In order to understand the following demo a simple introduction to enum
syntax
enum someenumeration {
  //enumeration definition goes here
}
defines an enumeration Enum CompassPoint {Case North case South case
  East case
  West
}

Access Assignment
var Directiontohead = Compasspoint.west

has confirmed the Directiontohead type can also be such a
Directiontohead =. East

A unique notation

Commodity Barcode Enumeration Enum Barcode {case UPCA (int, int, int.) Case QRCode (String)}//"Defines an enumeration type named Barcode, which can be a related value of UPCA (int,in T,int), or a string-type (string)-related value of QRCode. "//Create and assign var Productbarcode = BARCODE.UPCA (8, 85909_51226, 3) Productbarcode =. QRCode ("Abcdefghijklmnop")//Conditional filter print//You can extract each correlation value as a constant (with a let prefix) or as a variable (with var prefix) in the case branch code of switch to use switch Productbarcode {case. UPCA (Let-numbersystem, let-identifier, let-check): println ("upc-a with value of \ (Numbersystem), \ (identifier), \ (chec
k). ") Case.
QRCode (Let ProductCode): println ("QR code with value of \ (ProductCode).")}

Output "QR code with value of Abcdefghijklmnop." If all the relevant values of an enumeration member are extracted as constants, or they are all extracted as variables, for brevity, you can just place a var or let label before the member name, switch Productbarcode {case let. UPCA (Numbersystem, identifier, check): println ("upc-a with value of \ (Numbersystem), \ (identifier), \ (check).") Case L Et.
QRCode (ProductCode): println ("QR code with value of \ (ProductCode).")} Output "QR code with value of Abcdefghijklmnop."

Enumeration default values and optional binding judgments

Define
enum Planet:int {case
    Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
//based on default values Inference let
earthsorder = Planet.Earth.rawValue
//Earthsorder is 3

//optional binding. Or. Let
positiontofind = 9
If-let someplanet = Planet (rawvalue:positiontofind) {
    Switch-someplanet {case
    . Earth:
        println ("Mostly harmless")
    default:
        println ("Not a safe place for humans")
    }
} else { C16/>println ("There isn ' t a planet at position \ (positiontofind)")
}
//output "there isn ' t a planet at position 9
  //the first if according to the following expression is passed 9, can not be found, so the return is nil, can not be assigned to let constant, so into the Else branch, which is also a common method of determining the optional value
Closures Example-demo of official documents
Examples of closures for official documents
enum HttpResponse {case
    OK cases
    error (INT)
} Let

responses: [HttpResponse] = [. Error ( ),. Ok,. OK,. Error (404),. Error (403)] let
sortedresponses = responses.sorted {
    switch ($, $) {
    //Order Errors by code case let
    (. Error (Acode),. Error (Bcode)):
        return Acode < Bcode

    //All successes is Equivale NT, so none are before any other case
    (. OK,. ok): return false

    //Order errors before successes case
    (. Error ,. OK): Return True Case
    (. OK,. Error): Return False
    }
}
print (sortedresponses)
//      Prints "[. Error (403),. Error (404),. Error ($),. OK,. OK]"
[__lldb_expr_417.httpresponse.error (403), __lldb_ Expr_417.HTTPResponse.error (404), __lldb_expr_417.httpresponse.error (+), __lldb_expr_417.httpresponse.ok, __ Lldb_expr_417.HTTPResponse.ok]
Closure example-map function
Map Numbers.map (< #T # #transform: (int) throws, t## (int) throws, t#>)
//use map to iterate through the collection and do the same for each element in the collection Make
//is basically the default trailing closure, parameter only closure, omit (), omit return single-line expression closure can implicitly return the result of a single-line expression by hiding the return keyword let

digistname = [0: "Zore", 1: "One ", 2:" A ", 3:" Three ", 4:" Four ", 5:" Five ", 6:" Six ", 7:" Seven ", 8:" Eight ", 9:" Nine ") let
numbers = [213,44,658]

Let Stringnumbers = numbers.map {(num:int)-string in
    var num1 = num
    var string = "" While
    num1 > 0{< c8/>string = digistname[num1% 10]! + string
        num1 = Num1/10
    }
    return string
}
print (stringnumbers)
//["Twoonethree", " Fourfour "," sixfiveeight "] let

stringNumber2 = numbers.map {numberformatter.localizedstring (from:NSNumber.init (Value: $), Number:. Spellout)}
print (STRINGNUMBER2)
//["Hundred Thirteen", "Forty-four", "Six hundred f Ifty-eight "]
Capturing context variables

Closures can capture constants or variables in the context in which they are defined. Even though the original domain that defines these constants and variables does not already exist, closures can still reference and modify these values in the closure function body.

Swift's simplest form of closure is a nested function, which is a function defined in the function body of another function. Nested functions can capture all parameters of their external functions, as well as defined constants and variables

Func Makeincreasefunc (Extensionnumber localnumber:int),->int{
    var totalamount = 0;
    Func increasement ()->int{
        TotalAmount + localnumber
        return totalamount
    }
    return increasement
}

Let inc = Makeincreasefunc (EXTENSIONNUMBER:20)
Inc ()//+
Inc ()//

INC2 = Makeincreasefunc (Extensio NNUMBER:50)
INC2 ()///
INC2 ()//
the Makeincreasefunc function is nested inside the increasement, Nested function Increasement After capturing two values from the context TotalAmount and Localnumber, Makeincreasefunc returns the Increasement as the return value, each time the external call returns the value, will return the value of TotalAmount.

We assign the function to the variable so that we can invoke the function through the variable. The result of the operation allows us to discover that each call to Makeincreasefunc actually creates a new object, INC1, which is not the same as INC2. They have their own values and are not shared between them. This means that these functions are one-class functions, they are objects, can have multiple instances, can be assigned to variables, it feels like a destructor, the object is created internally, and then the object refers to some value of the external function, so that the local variable resident memory situation

/* func increasement ()->int{
    TotalAmount + localnumber
    return totalamount
}
*//
/ Look at this function alone, not pass any parameters, but by the value of the capture and increasement as the memory of the existence of the  capture is a strong reference, to ensure that the Makeincreasefunc hangs, its parameters and internal parameters can continue to use
A comparison of two simple examples

1. Function nesting, no return function

If a simple function is nested, the local variable will be reclaimed after it is used, and the function will be called the original data
func Add (num:int)->int
{
    var value =
    Adddouble ()->int{
        value + = num
        return value
    }
    return adddouble ()} let
testfun = add
Testfun ($)//
Testfun ($)///
Testfun (200)//300

2. Function nesting, return intrinsic function, implement closure

The internal nested function is returned by the return value, externally referenced, so that the local variable resident memory, which is considered a closure
func add2 (Num:int), ()->int
{
    var value =

    Func adddouble ()->int{
        value + = num
        return value
    }
    return adddouble} let

testFunc2 = ADD2 (num:200)
testFunc2 ()//+
TESTFUNC2 ()//
TESTFUNC2 ()//700
Personal Summary

1. Before you say closure, you need to know the concept of "free variables". In a scope, if you use a variable that is not declared in this scope, the variable is a free variable for that scope.
2. Closures are functions that refer to free variables. This quoted free variable will exist with this function, even if it has left the environment in which it was created. Another argument is that closures are not functions, but entities that are composed of functions and their associated reference environments. This is because closures can have multiple instances at run time, and different reference environments and the same combination of functions can produce different instances. There is only one instance of the function. I feel that if the closure and block as an object, it is very good to understand that your value is referenced by the object, then the object is not destroyed, regardless of whether the object created these variables have been destroyed, only strong pointers, these variables can also be used
3. The drawback of closures is that resident memory increases memory usage and is prone to memory leaks due to improper use.
4. Features: function nesting function, intrinsic function can refer to its external variables and parameters, can let local variables keepalive
5. Benefits: can be local variable resident memory, free self-control release, avoid the pollution of global variables, the existence of private members

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.