In Swift, there are four expressions: prefix expression, binary expression, simple expression, and suffix expression. Evaluating an expression returns a value, causes a side effect, or both.
Prefix and binary expressions can be used to use operators in short statements. Simplicity is conceptually the easiest way to get a value. Suffix expressions are similar to prefix expressions and dichotomous expressions in that they allow you to build more complex expressions; Examples include function calls and member fetching. We will explain each expression in detail in this section.
GRAMMAR OF AN EXPRESSION
Expression → prefix-expressionbinary-expressionsopt expression-list → expression expression,expression-list
The use of prefix expressions
Prefix expression adds a prefix operator to the front of an expression. The prefix operator is followed by an expression that can be understood as an argument to the prefix operator.
The Swift standard library provides the following prefix operators:
- + + since
- – the decrement
- ! Logic is not
- The ~ bit operation is reversed
-
- add
-
- Reduction of
Refer to the Basic Operators and Advanced Operators sections for details on how to use these Operators.
As a developer, it is particularly important to have a learning atmosphere and a communication circle. This is my iOS development public number: Programming Daxin, whether you are small white or big ox are welcome to enter. Let us progress together and develop together! (The group will provide some free study books collected by the group owner and hundreds of interview questions and answers documents for free!)
In addition to the library operators above, & can be placed In front of the variable name when a variable is passed as an argument In a function call, called in-out Parameters.
GRAMMAR OF A PREFIX EXPRESSION
Prefix-expression → prefix-operatorOptPostfix-expression prefix-expression → in-out expression in-out expression → prefix-operatoroptpostfix-expression &identifier
The use of dichotomous expressions
Dichotomy is an expression that places arguments on both sides of an operator. It has the following form:
left-hand argument operator right-hand argument
The Swift standard library provides the following binary operators:
- Power (no left-right correlation, priority 160)
- < < shift to the left
-
Moves to the right
- Multiplication and division (left correlation, priority 150)
-
- take
- / in addition to
- % die
- &* multiply (ignore overflow)
- &/ divide (ignore overflow)
- &% mode (ignore overflow)
- Ampersand and
- Addition and subtraction (left correlation, priority 140)
-
- add
-
- Reduction of
- & + overflow
- & – overflow
- | or
- ^ or
- Interval (no left-right correlation, priority 135)
- . Half-open interval
- . Closed interval
- Conversion (no left/right correlation, priority 132)
- Is Type Check
- As type Conversion
- Comparators (no left-right correlation, priority 130)
- < <
- <= is less than or equal to
-
Is greater than
-
= greater than or equal to
- = = is equal to the
- ! = is not equal to
- = = = the same
- ! = = not the same
- ~= Mode matching
- Concatenation (left correlation, priority 120)
- With && logic
- | | logic or
- Ternary operators (right correlation, priority 100)
- ? Ternary operator conditions
- Assignment operator (right correlation, priority 90)
- = assignment
- *= multiply and assign
- /= Divide and assign
- %= modulo and assign
- += autoappend and assign
- -= decrement and assign
- <<= moves left and assigns
-
= shift right and assign
- The ampersand = bit operation and union assignment
- ^= bit operation or union assignment
- | = operation or assignment
- &&= logical and union assignment
- | | and logic or assignment
See basic and advanced operators for instructions on how to use these operators.
Note: When parsing, the binary expression is broken down into a list. This list will be converted to a sequence to be evaluated. For example, 2 + 3 * 5 is initially understood as a list of five elements: 2, +, 3, *, 5. It then converts to the sequence form (2+(3*5)).
Syntax for binary expressions: Binary-expression → binary-operatorprefix-expression binary-expression → assignment-operatorprefix-expression Binary expression → conditional-operatorprefix-expression binary expression → type-casting-operator binary expression → binary-expressionbinary-expressionso
The use of assignment operators
The assignment operator assigns a new value to an expression. It is expressed as follows:
Expression = value
With this expression, the value on the right will be assigned to the expression on the left. If there is a tuple on the left, the value on the right must have the same number of elements (allowing multiple combinations). The assignment operation corresponds to the elements of each part. For example,
1. (a, _, (b, c)) = (" test ", 9.45, (12, 3)) 2. / / a is "test", is 12 b, c is 3, 9.45 automatically be ignored.Copy the code
The assignment operator returns no value.
The use of ternary operators
Conditional expression? This expression is executed if true and if false
If the conditional expression is true, the first expression is executed and its value is returned, otherwise the second expression is executed and its value is returned. Expressions that are not used are not executed.
See the three-wood operator for more examples.
The use of type conversion operators
There are two types of conversion operators: as and IS, of the form:
- Expression as type
- Expression as? type
- Expression is type
If the conversion to a particular type succeeds, the expression is returned as an instance of that particular type. The classic example is upward transition.
If this type of conversion fails, a compile-time error is raised.
If the success of the conversion is uncertain at compile time, the conversion expression becomes an optional value type. At run time, if the conversion is successful, the value of the expression will be packaged into an optional value and returned; otherwise, the value will be null, a typical example being a downcast.
1. class SomeSuperType {} 2. class SomeType: SomeSuperType {} 3. class SomeChildType: SomeType {} 4. let s = SomeSuperType () 6. let x = s as SomeSuperType 7. SomeSuperType 8. Let z = s as SomeChildType 11. SomeSuperType 8. The return type is SomeChildType?Copy the code
Using AS to determine a type has the same effect as a type declaration for the compiler. The following example illustrates this:
1. Let y1 = x as SomeType // let y2: SomeType = x //Copy the code
The IS operator checks the word runtime to see if the expression is of a specific type. Returns true if it is, false otherwise.
The result of a check at compile time must be indeterminate. The following example is illegal:
"Hello" is String. 2. "Hello" is IntCopy the code
For more explanations and examples of type conversions, see [for linkage].
Use of simple expressions
Simple expression is the most basic form of expression. They can be used alone or with other symbols to form prefix expressions, dichotomous expressions, and suffix expressions.
GRAMMAR OF A PRIMARY EXPRESSION
Primary-expression → identifiergeneric-argument-clauseopt primary-expression → literal-expression primary-expression → Self-expression primary-expression → superclass-expression primary-expression → closure-expression primary-expression → Closure -expression Parenthesized -expression primary-expression → implicit-member-expression primary-expression → wildcard-expression
The use of written expressions
Words from ordinary text (such as a string or number), array or dictionary, or the following special characters: Literal | Type | Value: — — — — — — — — — — — — — — — — — — — — — — — — : | : — — — — — — — — — — – : | : — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — : FILE | String | The name of the file in which it appears LINE | Int | The line number on which it appears. COLUMN | Int | The column number in which it begins. FUNCTION | String | The name of the declaration in which it appears.
Inside a function, __FUNCTION__ is the name of the function; Inside the method, it is the method name; It’s the name of the property in the get and set methods of the property; In special members such as init and subscript, it is the name of the keyword; At the top level of the file, it is the current model name.
The literal declaration of an array is a collection of ordered values. Its structure is as follows: [value1, value2…
The last expression in the array can be followed by a period. An empty array declaration can be represented by an empty bracket ([]). The array value is of type T[], where T represents the type of the expression inside the array. If the elements are of different types, T represents their smallest superclass.
The literal declaration of a dictionary is an unordered collection of key-value pairs. It has the following expression: [key:value1, key:value2,…
The last expression in the dictionary can be followed by a period. An empty dictionary is declared by enclosing a colon ([:]) in parentheses to distinguish it from an empty array representation.
The type of the Dictionary is Dictionary< keyType, ValueType>, where keyType is the type of the key and ValueType is the type of its corresponding value. If the dictionary has more than one type, keytype and ValueType make them represent the minimum superclass of the ValueType.
GRAMMAR OF A LITERAL EXPRESSION
Literal-expression → literal literal-expression → array-literal dictionary-literal literal-expression → FILE LINE COLUMN FUNCTION array-literal → [array-literal-itemsopt] array-literal-items → array-literal-item,opt Array-literal-item,array-literal-items array-literal-item → expression dictionary-literal-items → [dictionary-literal-items] [:] dictionary-literal-items → dictionary-literal-item,opt dictionary-literal-item,dictionary-literal-items Dictionary – literal – item – > expression: expression
The use of the Self
Self is an explicit reference to the current type or an instance of the current class. Its use method is as follows:
1. self
2. self.`member name`
3. self[`subscript index`]
4. self(`initializer arguments`)
5. self.init(`initializer arguments`)
Copy the code
In a constructor, subscript, or instance method, self refers to a reference to the current instance. In static or class methods, self refers to a reference to the current class.
Self is used to explicitly refer to accessing a member variable when a variable of the same name exists in the same scope, such as when a temporary variable has the same name as the member variable:
1. class SomeClass {
2. var greeting: String
3. init(greeting: String) {
4. self.greeting = greeting
5. }
6. }
Copy the code
In a mutating method, you can assign self to a new instance, for example:
Struct Point {2. Var x = 0.0, y = 0.0 3. Double) { 4. self = Point(x: x + deltaX, y: y + deltaY) 5. } 6. }Copy the code
GRAMMAR OF A SELF EXPRESSION
Self -expression → self-expression → self. Identifier Self -expression → self[expression] self-expression → self
Use of superclasses
Superclass expressions allow a class to be associated with its superclass. The following cases:
1. super.`member name`
2. super[`subscript index`]
3. super.init(`initializer arguments`)
Copy the code
The first form retrieves the members of the superclass. The second form gets the implementation of the corner method of the superclass. The third form can be used to access the initializer of the superclass.
Subclasses use superclasses to implement their own members, subscripts, and initializers.
GRAMMAR OF A SUPERCLASS EXPRESSION
Superclass-expression → superclass-method-expression superclass-subscript-expression superclass-initialer-expression Superclass-method-expression → super.identifier Superclass-subscript-expression → super[expression] Superclass –, initializer expression – super init
Use of closures
Closures create a closed interval and, in other languages, are also called lambda or anonymous functions. Like method declarations, closures contain statements for execution and value from the closure interval. It has the following form:
1. { (`parameters`) -> `return type` in
2. `statements`
3. }
Copy the code
The arguments and forms are the same as the declaration of the function.
It can be written more succinctly:
- A closure may omit its argument type and return value type. If the parameter name and its type are omitted, the preceding
in
Key words; If the type cannot be inferred, a compile-time error is generated. - If a closure omits its argument name, its arguments are implicitly named with their position number: 0, 1,1,1, and so on.
- Closures that have only one expression return the value of the expression by default. When there is an expression operation reference type around, the content of that expression is also involved. The following closures are equivalent:
1. myFunction { (x: Int, y: Int) -> Int in return x + y }
2. myFunction { (x, y) in return x + y }
3. myFunction { return $0 + $1 }
4. myFunction { $0 + $1 }
Copy the code
For more information about closures passing arguments to functions, see The use of function calls.
Closures can explicitly get specific values using a Capture list. The contents of the crawl list are enclosed by brackets and separated by commas, followed by a list of parameters. When you use a crawl list, you must write the in keyword even if you omit the parameter name, parameter type, and return value type.
Each entry in the crawl list can be marked weak or unowned to catch weak or unheaded references of the value.
1. myFunction { print(self.title) } // strong capture 2. myFunction { [weak self] in print(self! .title) } // weak captureCopy the code
You can also add a judgment expression to a non-anonymous value, and when the closure executes, the expression will be judged and fetched with a specific reference strength. Such as:
1. // Weak capture of "self.parent" as "parent" 2. myFunction { [weak parent = self.parent] in print(parent! .title) }Copy the code
For more information and examples of closures, see Closures.
GRAMMAR OF A CLOSURE EXPRESSION
Closure -expression → {closure-signatureoptstatements} closure-signature → parameter-clausefunction-resultoptin Closure – Signature → Identifier – ListFunction -resultoptin closure-signature → The capture – listparameter – clausefunction – resultoptin closure – people like to capture – listidentifier – listfunction – resultoptin Closure -signature → capture- Listin capture-list → [capture-specifierexpression] capture-specifier → weak unowned unowned(safe) unowned(unsafe)
Use of anonymous members
Anonymous members are a simple form of accessing members, such as in the context of enumerated types or class methods, where reference types can be inferred. It has the form.member name
Such as:
1. var x = MyEnumeration.SomeValue
2. x = .AnotherValue
Copy the code
GRAMMAR OF A IMPLICIT MEMBER EXPRESSION implicit-member-expression → .identifier
The use of parenthesis expressions
Parenthetical expressions Internal expressions are separated by commas and external expressions are enclosed by parentheses. Each expression can have an internal expression name separated by a colon. Its format is as follows: (Identifier 1: expression 1, identifier 2: expression 2…)
We can pass parameters to function calls using parenthesis expressions. If there is only one value in parentheses, the type of the parenthesis expression is the type of that value. For example, (1) is of type Int, not (Int).
GRAMMAR OF A PARENTHESIZED EXPRESSION PARENTHESIZED – EXPRESSION → (EXPRESSION -element-listopt) EXPRESSION -element-list → Expression -element expression-element,expression-element-list expression-element → expression identifier:expression
The use of placeholder expressions
Placeholders are expressed to intentionally omit a value during assignment. For example, in the example below, 10 is assigned to x and 20 is ignored. (x, _) = (10, 20)
GRAMMAR OF A WILDCARD EXPRESSION WILDCARD – EXPRESSION → _
Use of post-modifier expressions
You can create a decorated expression using a decorated operator or other decorated syntax. Syntactically, all simple expressions are also post-decorated expressions.
The Swift standard library provides the following post-modifier operators:
- + + since added
- – the decrement
For the use of this operator, [see basic and advanced operators;] (c.biancheng.net/cpp/html/22…).
GRAMMAR OF A POSTFIX EXPRESSION
Postfix-expression → primary-expression postfix-expression → postfix-expression postfix-expression → postfix-expressionpostfix-operator postfix-expression → Function-call-expression postfix-expression → initializer-expression postfix-expression → explicit-member-expression Postfix-expression → postfix-self-expression postfix-expression → dynamic-type-expression postfix-expression → Subscript-expression postfix-expression → formed-value-expression postfix-expression → optional-chaining-expression
The method of a function call
The function is called using the following methods: Function name parentheses, which contain the parameter list. Multiple parameters are separated by commas. Function name(argument value 1, argument value 2)
Function names can be named after any name that has a function type.
If the argument name is defined in the function declaration, the argument name must be preceded by the argument value and separated by a colon, as shown in the following example: function name(argument name 1: argument value 1, argument name 2: argument value 2)
A function can be called with a closure suffix following the closing parenthesis. The postfix code block is also an argument to the function. SomeFunction (x, {0 == 13}) someFunction(x) {0 == 13}
If the closure is the only argument, the parentheses can be omitted. SomeMethod () {0 == 13} mydata.somemethod {0 == 13} mydata.somemethod {0 == 13}
GRAMMAR OF A FUNCTION CALL EXPRESSION
Function-call-expression → postfix-expressionparenthesed-expression function-call-expression → postfix-expressionparenthesed-expression Postfix – expressionparenthesized – expressionopttrailing – closure trailing – closure – closure – expression
Usage of initializer expressions
The initialization expression accesses the initializer of that type. Its structure is as follows: expression.init(initializer arguments)
Initializers are called in the same way as function calls, but unlike functions, initializers are not a value. Such as:
1. Var x = SomeClass. SomeClassFunction / / var y = SomeClass right. The init / / errorsCopy the code
You can also use an initializer to call a superclass’s initializer.
1. class SomeSubClass: SomeSuperClass { init() { // subclass initialization goes here super.init() } } 3. GRAMMAR OF AN INITIALIZER EXPRESSION 5., initializer expression - postfix - expression. The initCopy the code
Use of explicit member expressions
Explicit member expressions can access named classes, tuples, or members of components. Delimit the expression from the member name with a dot. expression.member name
Named member variables can be part of a class declaration or an extension of it. Such as:
1. class SomeClass {
2. var someProperty = 42
3. }
4. let c = SomeClass()
5. let y = c.someProperty
6. // Member access
Copy the code
Tuples are named implicitly and sequentially with numbers starting from zero. Var t = (10, 20, 30) t.0 = t.1 // now t is (20, 20, 30)
A component member can get its top-level declaration.
GRAMMAR OF AN EXPLICIT MEMBER EXPRESSION
Explicit-member-expression → postfix-expression. Decimal -digit explicit-member-expression → postfix-expression.identifiergeneric-argument-clauseopt
The use of the suffix expression self
The suffix expression for self is formed by adding “. Self “to the expression or type name. Its form is as follows: expression. Self type. Self
The first form yields the value of the expression. For example, x. elf is the x value.
The second form gets the value of the type. You can use this form to get a type in the form of a value. For example. SomeClass. Self is the SomeClass class that you can pass to functions or methods that take arguments of the class type.
GRAMMAR OF A SELF EXPRESSION
Postfix – self – expression and postfix – expression. The self
Use of dynamically typed expressions
DynamicType expressions are formed by adding. DynamicType to the expression. Its structure is as follows: expression.dynamictype
Expressions cannot be class names. The full dynamicType expression gets the run-time class name value of the expression. The following cases:
1. class SomeBaseClass { 2. class func printClassName() { 3. println("SomeBaseClass") 4. } 5. } 6. class SomeSubClass: SomeBaseClass { 7. override class func printClassName() { 8. println("SomeSubClass") 9. } 10. } 11. let someInstance: SomeBaseClass = SomeSubClass() 12. But 13. / / someInstance runtime type is SomeSubClass 14. SomeInstance. DynamicType. PrintClassName () 15. / / print "SomeSubClass"Copy the code
GRAMMAR OF A DYNAMIC TYPE EXPRESSION
Dynamic – type – expression and postfix – expression. DynamicType
Use of subscript expressions
The subscript expression uses the set method of the corresponding get method to get the subscript. Its format is as follows: expression[index expressions]
To get the value of a subscript expression, the subscript expression is called as an argument to the get method of the corner marker. Of course, to set its value, the subscript’s set method is called in the same way.
For more information about subscript declarations, see Subscript declarations.
GRAMMAR OF A SUBSCRIPT EXPRESSION subscript-expression → postfix-expression[EXPRESSION -list]
Enforce the use of unpack expressions
When an optional value is not empty, the optional value can be forcibly unpacked. Its structure is as follows: Expression!
Self-judge the use of link expressions
Self-judging links are easy to use by suffixing them with optional values. Its structure is as follows: expression.?
The suffix? Returns its arguments as optional values.
In the expression of suffixes, the value of self-judging link is very special. If the link is empty, subsequent expressions are not executed and the entire expression returns empty. If the self-determined link result is not empty, the expression is unpacked and the remaining postfix expression continues. In either case, the value of a postfix expression is an optional value type.
If the self-determination link is nested, only the outermost optional value type is returned. In the following example, if c is not nil, its value is unpacked and used to get the values of.property and.performAction(). The entire c? .property.performAction() is an optional value type. var c: SomeClass? var result: Bool? = c? .property.performAction()
The following example illustrates a situation where self-judging links are not used.
1. if let unwrappedC = c {
2. result = unwrappedC.property.performAction()
3. }
Copy the code
GRAMMAR OF AN OPTIONAL-CHAINING EXPRESSION optional-chaining-expression → postfix-expression?