Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

the-swift-rogramming-language

.pdf
Скачиваний:
13
Добавлен:
11.05.2015
Размер:
4.27 Mб
Скачать

Assignment (Right associative, precedence level 90)

= Assign

*= Multiply and assign /= Divide and assign

%= Remainder and assign += Add and assign

-= Subtract and assign

<<= Left bit shift and assign >>= Right bit shift and assign &= Bitwise AND and assign ^= Bitwise XOR and assign |= Bitwise OR and assign &&= Logical AND and assign ||= Logical OR and assign

For information about the behavior of these operators, see Basic Operators and Advanced Operators.

N O T E

At parse time, an expression made up of binary operators is represented as a flat list. This list is transformed into a tree by applying operator precedence For example, the expression 2 + 3 * 5 is initially understood as a flat list of five items, 2, +, `` 3``, *, and 5. This process transforms it into the tree (2 + (3 * 5)).

G R A M M A R O F A B I N A R Y E X P R E S S I O N

binary-expressionbinary-operator prefix-expression binary-expressionassignment-operator prefix-expression binary-expressionconditional-operator prefix-expression binary-expressiontype-casting-operator binary-expressionsbinary-expression binary-expressions opt

Assignment Operator

The assigment operator sets a new value for a given expression. It has the following form:

expression = value

The value of the expression is set to the value obtained by evaluating the value. If the expression is a tuple, the value must be a tuple with the same number of elements. (Nested tuples are allowed.) Assignment is performed from each part of the value to the corresponding part of the expression. For example:

(a, _, (b, c)) = ("test", 9.45, (12, 3))

// a is "test", b is 12, c is 3, and 9.45 is ignored

The assignment operator does not return any value.

G R A M M A R O F A N A S S I G N M E N T O P E R A T O R

assignment-operator → =

Ternary Conditional Operator

The ternary conditional operator evaluates to one of two given values based on the value of a condition. It has the following form:

condition ? expression used if true : expression used if false

If the condition evaluates to true, the conditional operator evaluates the first expression and returns its value. Otherwise, it evaluates the second expression and returns its value. The unused expression is not evaluated.

For an example that uses the ternary conditional operator, see Ternary Conditional Operator.

G R A M M A R O F A C O N D I T I O N A L O P E R A T O R

conditional-operator → ? expression :

Type-Casting Operators

There are two type-casting operators, the as operator and the is operator. They have the following form:

expression as type

expression as? type

expression is type

The as operator performs a cast of the expression to the specified type. It behaves as follows:

If conversion to the specified type is guaranteed to succeed, the value of the expression is returned as an instance of the specified type. An example is casting from a subclass to a superclass.

If conversion to the specified type is guaranteed to fail, a compile-time error is raised.

Otherwise, if it’s not known at compile time whether the conversion will succeed, the type of the cast expresion is an optional of the specified type. At runtime, if the cast succeeds, the value of expression is wrapped in an optional and returned; otherwise, the value returned is nil. An example is casting from a superclass to a subclass.

class SomeSuperType {}

class SomeType: SomeSuperType {} class SomeChildType: SomeType {} let s = SomeType()

let x = s as SomeSuperType // known to succeed; type is SomeSuperType let y = s as Int // known to fail; compile-time error

let z = s as SomeChildType // might fail at runtime; type is SomeChildType?

Specifying a type with as provides the same information to the compiler as a type annotation, as shown in the following example:

let y1 = x as SomeType // Type information from 'as'

let y2: SomeType = x // Type information from an annotation

The is operator checks at runtime to see whether the expression is of the specified type. If so, it returns true; otherwise, it returns false.

The check must not be known to be true or false at compile time. The following are invalid:

"hello" is String

"hello" is Int

For more information about type casting and to see more examples that use the typecasting operators, see Type Casting.

G R A M M A R O F A T Y P E - C A S T I N G O P E R A T O R

type-casting-operator → is type as ? opt type

Primary Expressions

Primary expressions are the most basic kind of expression. They can be used as expressions on their own, and they can be combined with other tokens to make prefix expressions, binary expressions, and postfix expressions.

G R A M M A R O F A P R I M A R Y E X P R E S S I O N

primary-expressionidentifier generic-argument-clause opt primary-expressionliteral-expression primary-expressionself-expression

primary-expressionsuperclass-expression primary-expressionclosure-expression primary-expressionparenthesized-expression primary-expressionimplicit-member-expression primary-expressionwildcard-expression

Literal Expression

A literal expression consists of either an ordinary literal (such as a string or a number), an array or dictionary literal, or one of the following special literals:

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, the value of __FUNCTION__ is the name of that function, inside a method it is the name of that method, inside a property getter or setter it is the name of that property, inside special members like init or subscript it is the name of that keyword, and at the top level of a file it is the name of the current module.

An array literal is an ordered collection of values. It has the following form:

[ value 1 , value 2 , ... ]

The last expression in the array can be followed by an optional comma. An empty array literal is written as an empty pair of brackets ([]). The value of an array literal has type T[], where T is the type of the expressions inside it. If there are expressions of multiple types, T is their closest common supertype.

A dictionary literal is an unordered collection of key-value pairs. It has the following form:

[ key 1 : value 1 , key 2 : value 2 , ... ]

The last expression in the dictionary can be followed by an optional comma. An empty dictionary literal is written as a colon inside a pair of brackets ([:]) to distinguish it from an empty array literal. The value of a dictionary literal has type Dictionary<KeyType, ValueType>, where KeyType is the type of its key expressions and ValueType is the type of its value expressions. If there are expressions of multiple types, KeyType and ValueType are the closest common supertype for their respective values.

G R A M M A R O F A L I T E R A L E X P R E S S I O N

literal-expression → literal

literal-expressionarray-literal dictionary-literal

literal-expression__FILE__ __LINE__ __COLUMN__ __FUNCTION__

array-literal[ array-literal-items opt ]

array-literal-itemsarray-literal-item , opt array-literal-item , array-literal-items array-literal-itemexpression

dictionary-literal → [ dictionary-literal-items ] [ : ] dictionary-literal-items → dictionary-literal-item , opt dictionary-literal-

item , dictionary-literal-items dictionary-literal-itemexpression : expression

Self Expression

The self expression is an explicit reference to the current type or instance of the type in which it occurs. It has the following forms:

self

self. member name self[ subscript index ]

self( initializer arguments ) self.init( initializer arguments )

In an initializer, subscript, or instance method, self refers to the current instance of the type in which it occurs. In a static or class method, self refers to the current type in which it occurs.

The self expression is used to specify scope when accessing members, providing disambiguation when there is another variable of the same name in scope, such as a function parameter. For example:

class SomeClass { var greeting: String

init(greeting: String) { self.greeting = greeting

}

}

In a mutating method of value type, you can assign a new instance of that value type to self. For example:

struct Point {

var x = 0.0, y = 0.0

mutating func moveByX(deltaX: Double, y deltaY: Double) { self = Point(x: x + deltaX, y: y + deltaY)

}

}

G R A M M A R O F A S E L F E X P R E S S I O N

self-expressionself self-expressionself . identifier self-expressionself [ expression ] self-expressionself . init

Superclass Expression

A superclass expression lets a class interact with its superclass. It has one of the following forms:

super. member name super[ subscript index ]

super.init( initializer arguments )

The first form is used to access a member of the superclass. The second form is used to access the superclass’s subscript implementation. The third form is used to access an initializer of the superclass.

Subclasses can use a superclass expression in their implementation of members, subscripting, and initializers to make use of the implementation in their superclass.

G R A M M A R O F A S U P E R C L A S S E X P R E S S I O N

superclass-expressionsuperclass-method-expression superclass-subscript- expression superclass-initializer-expression

superclass-method-expression → super . identifier superclass-subscript-expression → super [ expression ] superclass-initializer-expression → super . init

Closure Expression

A closure expression creates a closure, also known as a lambda or an anonymous function in other programming languages. Like function declarations, closures contain statements which they execute, and they capture values from their enclosing scope. It has the following form:

{ ( parameters ) -> return type in

statements

}

The parameters have the same form as the parameters in a function declaration, as described in Function Declaration.

There are several special forms that allow closures to be written more concisely:

A closure can omit the types of its parameters, its return type, or both. If you omit the parameter names and both types, omit the in keyword before the statements. If the omitted types can’t be inferred, a compile-time error is raised.

A closure may omit names for its parameters. Its parameters are then implicitly named $ followed by their position: $0, $1, $2, and so on.

A closure that consists of only a single expression is understood to return the value of that expression. The contents of this expression is also considered when performing type inference on the surrounding expression.

The following closure expressions are equivalent:

myFunction {

(x: Int, y: Int) -> Int in return x + y

}

myFunction { (x, y) in return x + y

}

nction { return $0 + $1 }

nction { $0 + $1 }

For information about passing a closure as an argument to a function, see Function Call Expression.

A closure expression can explicitly specify the values that it captures from the surrounding

scope using a capture list. A capture list is written as a comma separated list surrounded by square brackets, before the list of parameters. If you use a capture list, you must also use the in keyword, even if you omit the parameter names, parameter types, and return type.

Each entry in the capture list can be marked as weak or unowned to capture a weak or unowned reference to the value.

 

myFunction { print(self.title) }

// strong capture

 

myFunction { [weak self] in print(self!.title) }

// weak capture

 

myFunction { [unowned self] in print(self.title) } // unowned capture

 

 

 

You can also bind arbitrary expression to named values in the capture list. The expression is evaluated when the closure is formed, and captured with the specified strength. For example:

// Weak capture of "self.parent" as "parent"

myFunction { [weak parent = self.parent] in print(parent!.title) }

For more information and examples of closure expressions, see Closure Expressions.

G R A M M A R O F A C L O S U R E E X P R E S S I O N

closure-expression{ closure-signature opt statements }

closure-signatureparameter-clause function-result opt in closure-signatureidentifier-list function-result opt in closure-signaturecapture-list parameter-clause function-result opt in closure-signaturecapture-list identifier-list function-result opt in closure-signaturecapture-list in

capture-list[ capture-specifier expression ]

capture-specifierweak unowned unowned(safe) unowned(unsafe)

Implicit Member Expression

An implicit member expression is an abbreviated way to access a member of a type, such as an enumeration case or a class method, in a context where type inference can determine the implied type. It has the following form:

. member name

For example:

var x = MyEnumeration.SomeValue

x = .AnotherValue

G R A M M A R O F A I M P L I C I T M E M B E R E X P R E S S I O N

implicit-member-expression → . identifier

Parenthesized Expression

A parenthesized expression consists of a comma-separated list of expressions surrounded by parentheses. Each expression can have an optional identifier before it, separated by a colon (:). It has the following form:

( identifier 1 : expression 1 , identifier 2 : expression 2 , ... )

Use parenthesized expressions to create tuples and to pass arguments to a function call. If there is only one value inside the parenthesized expression, the type of the parenthesized expression is the type of that value. For example, the type of the parenthesized expression (1) is Int, not (Int).

G R A M M A R O F A P A R E N T H E S I Z E D E X P R E S S I O N

parenthesized-expression → ( expression-element-list opt ) expression-element-list → expression-element expression-element , expression-

element-list

expression-elementexpression identifier : expression

Wildcard Expression

A wildcard expression is used to explicitly ignore a value during an assignment. For example, in the following assignment 10 is assigned to x and 20 is ignored:

(x, _) = (10, 20)

// x is 10, 20 is ignored

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]