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

The_Swift_Programming_Language

.pdf
Скачиваний:
24
Добавлен:
18.03.2015
Размер:
5 Мб
Скачать
☆

As with other protocol member declarations, these property declarations declare only the getter and setter requirements for types that conform to the protocol. As a result, you don’t implement the getter or setter directly in the protocol in which it is declared.

The getter and setter requirements can be satisfied by a conforming type in a variety of ways. If a property declaration includes both the get and set keywords, a conforming type can implement it with a stored variable property or a computed property that is both readable and writeable (that is, one that implements both a getter and a setter). However, that property declaration can’t be implemented as a constant property or a read-only computed property. If a property declaration includes only the get keyword, it can be implemented as any kind of property. For examples of conforming types that implement the property requirements of a protocol, see Property Requirements.

See also Variable Declaration.

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

​protocol-property-declaration → variable-declaration-head variable-name typeannotation getter-setter-keyword-block

Protocol Method Declaration

Protocols declare that conforming types must implement a method by including a protocol method declaration in the body of the protocol declaration. Protocol method declarations have the same form as function declarations, with two exceptions: They don’t include a function body, and you can’t provide any default parameter values as part of the function declaration. For examples of conforming types that implement the method requirements of a protocol, see Method Requirements.

To declare a class or static method requirement in a protocol declaration, mark the method declaration with the class keyword. Classes that implement this method also declare the method with the class keyword. Structures that implement it must declare the method with the static keyword instead. If you’re implementing the method in an extension, use the class keyword if you’re extending a class and the static keyword if you’re extending a structure.

See also Function Declaration.

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

​protocol-method-declaration → function-head function-name generic-parameter- clause opt function-signature

Protocol Initializer Declaration

Protocols declare that conforming types must implement an initializer by including a protocol initializer declaration in the body of the protocol declaration. Protocol initializer declarations have the same form as initializer declarations, except they don’t include the initializer’s body.

See also Initializer Declaration.

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

​protocol-initializer-declaration → initializer-head generic-parameter- clause opt parameter-clause

Protocol Subscript Declaration

Protocols declare that conforming types must implement a subscript by including a protocol subscript declaration in the body of the protocol declaration. Protocol property declarations have a special form of a subscript declaration:

subscript ( parameters ) -> return type { get set }

Subscript declarations only declare the minimum getter and setter implementation requirements for types that conform to the protocol. If the subscript declaration includes both the get and set keywords, a conforming type must implement both a getter and a setter clause. If the subscript declaration includes only the get keyword, a conforming type must implement at least a getter clause and optionally can implement a setter clause.

See also Subscript Declaration.

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

​protocol-subscript-declaration → subscript-head subscript-result getter-setter- keyword-block

Protocol Associated Type Declaration

Protocols declare associated types using the keyword typealias. An associated type provides an alias for a type that is used as part of a protocol’s declaration. Accosiated types are similiar to type paramters in generic parameter clauses, but they’re associated with Self in the protocol in which they’re declared. In that context, Self refers to the eventual type that conforms to the protocol. For more information and examples, see Associated Types.

See also Type Alias Declaration.

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

​protocol-associated-type-declaration → typealias-head type-inheritance- clause opt typealias-assignment opt

Initializer Declaration

An initializer declaration introduces an initializer for a class, structure, or enumeration into your program. Initializer declarations are declared using the keyword init and have two basic forms.

Structure, enumeration, and class types can have any number of initializers, but the rules and associated behavior for class initializers are different. Unlike structures and enumerations, classes have two kinds of initializers: designated initializers and convenience initializers, as described in Initialization.

The following form declares initializers for structures, enumerations, and designated initializers of classes:

init( parameters ) {

statements

}

A designated initializer of a class initializes all of the class’s properties directly. It can’t call any other initializers of the same class, and if the class has a superclass, it must call one of the superclass’s designated initializers. If the class inherits any properties from its superclass, one of the superclass’s designated initializers must be called before any of these properties can be set or modified in the current class.

Designated initializers can be declared in the context of a class declaration only and therefore can’t be added to a class using an extension declaration.

Initializers in structures and enumerations can call other declared initializers to delegate part or all of the initialization process.

To declare convenience initializers for a class, prefix the initializer declaration with the context-sensitive keyword convenience.

convenience init( parameters ) {

statements

}

Convenience initializers can delegate the initialization process to another convenience initializer or to one of the class’s designated initializers. That said, the initialization

processes must end with a call to a designated initializer that ultimately initializes the class’s properties. Convenience initializers can’t call a superclass’s initializers.

You can mark designated and convenience initializers with the required attribute to require that every subclass implement the initializer. Because designated initializers are not inherited by subclasses, they must be implemented directly. Required convenience initializers can be either implemented explicitly or inherited when the subclass directly implements all of the superclass’s designated initializers (or overrides the designated initializers with convenience initializers). Unlike methods, properties, and subscripts, you don’t need to mark overridden initializers with the override keyword.

To see examples of initializers in various type declarations, see Initialization.

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

​initializer-declaration → initializer-head generic-parameter-clause opt parameterclause initializer-body

​initializer-head → attributes opt convenience opt init ​initializer-body → code-block

Deinitializer Declaration

A deinitializer declaration declares a deinitializer for a class type. Deinitializers take no parameters and have the following form:

deinit {

statements

}

A deinitializer is called automatically when there are no longer any references to a class object, just before the class object is deallocated. A deinitializer can be declared only in the body of a class declaration—but not in an extension of a class—and each class can have at most one.

A subclass inherits its superclass’s deinitializer, which is implicitly called just before the subclass object is deallocated. The subclass object is not deallocated until all deinitializers in its inheritance chain have finished executing.

Deinitializers are not called directly.

For an example of how to use a deinitializer in a class declaration, see Deinitialization.

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

​deinitializer-declaration → attributes opt deinit code-block

Extension Declaration

An extension declaration allows you to extend the behavior of existing class, structure, and enumeration types. Extension declarations begin with the keyword extension and have the following form:

extension type : adopted protocols {

declarations

}

The body of an extension declaration contains zero or more declarations. These declarations can include computed properties, computed static properties, instance methods, static and class methods, initializers, subscript declarations, and even class, structure, and enumeration declarations. Extension declarations can’t contain destructor or protocol declarations, store properties, property observers, or other extension declarations. For a discussion and several examples of extensions that include various kinds of declarations, see Extensions.

Extension declarations can add protocol conformance to an existing class, structure, and enumeration type in the adopted protocols. Extension declarations can’t add class inheritance to an existing class, and therefore the type-inheritance-clause in an extension declaration contains only a list of protocols.

Properties, methods, and initializers of an existing type can’t be overridden in an extension of that type.

Extension declarations can contain initializer declarations. That said, if the type you’re extending is defined in another module, an initializer declaration must delegate to an initializer already defined in that module to ensure members of that type are properly initialized.

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

​extension-declaration → extension type-identifier type-inheritance- clause opt extension-body

​extension-body → { declarations opt }

Subscript Declaration

A subscript declaration allows you to add subscripting support for objects of a particular type and are typically used to provide a convenient syntax for accessing the elements in a collection, list, or sequence. Subscript declarations are declared using the keyword

subscript and have the following form:

subscript ( parameters ) -> return type { get {

statements

}

set( setter name ) { statements

}

}

Subscript declarations can appear only in the context of a class, structure, enumeration, extension, or protocol declaration.

The parameters specify one or more indexes used to access elements of the corresponding type in a subscript expression (for example, the i in the expression object[i]). Although the indexes used to access the elements can be of any type, each parameter must include a type annotation to specify the type of each index. The return type specifies the type of the element being accessed.

As with computed properties, subscript declarations support reading and writing the value of the accessed elements. The getter is used to read the value, and the setter is used to write the value. The setter clause is optional, and when only a getter is needed, you can omit both clauses and simply return the requested value directly. That said, if you provide a setter clause, you must also provide a getter clause.

The setter name and enclosing parentheses are optional. If you provide a setter name, it is used as the name of the parameter to the setter. If you do not provide a setter name, the default parameter name to the setter is value. That type of the setter name must be the same as the return type.

You can overload a subscript declaration in the type in which it is declared, as long as the parameters or the return type differ from the one you’re overloading. You can also override a subscript declaration inherited from a superclass. When you do so, you must mark the overridden subscript declaration with the override keyword.

You can also declare subscripts in the context of a protocol declaration, as described in Protocol Subscript Declaration.

For more information about subscripting and to see examples of subscript declarations, see Subscripts.

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

​subscript-declaration → subscript-head subscript-result code-block

attributes opt

​subscript-declaration → subscript-head subscript-result getter-setter-block ​subscript-declaration → subscript-head subscript-result getter-setter-keyword-

block

​subscript-head → attributes opt subscript parameter-clause ​subscript-result → -> type

Operator Declaration

An operator declaration introduces a new infix, prefix, or postfix operator into your program and is declared using the contextual keyword operator.

You can declare operators of three different fixities: infix, prefix, and postfix. The fixity of an operator specifies the relative position of an operator to its operands.

There are three basic forms of an operator declaration, one for each fixity. The fixity of the operator is specified by including the contextual keyword infix, prefix, or postfix between operator and the name of the operator. In each form, the name of the operator can contain only the operator characters defined in Operators.

The following form declares a new infix operator:

operator infix operator name {

precedence precedence level

associativity associativity

}

An infix operator is a binary operator that is written between its two operands, such as the familiar addition operator (+) in the expression 1 + 2.

Infix operators can optionally specify a precedence, associativity, or both.

The precedence of an operator specifies how tightly an operator binds to its operands in the absence of grouping parentheses. You specify the precedence of an operator by writing the contextual keyword precedence followed by the precedence level. The precedence level can be any whole number (decimal integer) from 0 to 255; unlike decimal integer literals, it can’t contain any underscore characters. Although the precedence level is a specific number, it is significant only relative to another operator. That is, when two operators compete with each other for their operands, such as in the expression 2 + 3 * 5, the operator with the higher precedence level binds more tightly to its operands.

The associativity of an operator specifies how a sequence of operators with the same precedence level are grouped together in the absence of grouping parentheses. You specify the associativity of an operator by writing the contextual keyword associativity

followed by the associativity, which is one of the contextual keywords left, right, or none. Operators that are left-associative group left-to-right. For example, the subtraction operator (-) is left-associative, and therefore the expression 4 - 5 - 6 is grouped as (4 - 5) - 6 and evaluates to -7. Operators that are right-associative group right-to-left, and operators that are specified with an associativity of none don’t associate at all. Nonassociative operators of the same precedence level can’t appear adjacent to each to other. For example, 1 < 2 < 3 is not a valid expression.

Infix operators that are declared without specifying a precedence or associativity are initialized with a precedence level of 100 and an associativity of none.

The following form declares a new prefix operator:

operator prefix operator name {}

A prefix operator is a unary operator that is written immediately before its operand, such as the prefix increment operator (++) is in the expression ++i.

Prefix operators declarations don’t specify a precedence level. Prefix operators are nonassociative.

The following form declares a new postfix operator:

operator postfix operator name {}

A postfix operator is a unary operator that is written immediately after its operand, such as the postfix increment operator (++) is in the expression i++.

As with prefix operators, postfix operator declarations don’t specify a precedence level. Postfix operators are nonassociative.

After declaring a new operator, you implement it by declaring a function that has the same name as the operator. To see an example of how to create and implement a new operator, see Custom Operators.

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

​operator-declaration → prefix-operator-declaration postfix-operator-declaration infix-operator-declaration

​prefix-operator-declaration → operator prefix operator { } ​postfix-operator-declaration → operator postfix operator { } ​infix-operator-declaration → operator infix operator { infix-operator-attributes opt }

​infix-operator-attributes → precedence-clause opt associativity-clause opt ​precedence-clause → precedence precedence-level

​precedence-level → Digit 0 through 255 ​associativity-clause → associativity associativity

​associativity → left right none

class_protocol

Attributes

Attributes provide more information about a declaration or type. There are two kinds of attributes in Swift, those that apply to declarations and those that apply to types. For instance, the required attribute—when applied to a designated or convenience initializer declaration of a class—indicates that every subclass must implement that initializer. And the noreturn attribute—when applied to a function or method type—indicates that the function or method doesn’t return to its caller.

You specify an attribute by writing the @ symbol followed by the attribute’s name and any arguments that the attribute accepts:

@attribute name

@attribute name ( attribute arguments )

Some declaration attributes accept arguments that specify more information about the attribute and how it applies to a particular declaration. These attribute arguments are enclosed in parentheses, and their format is defined by the attribute they belong to.

Declaration Attributes

You can apply a declaration attribute to declarations only. However, you can also apply the noreturn attribute to a function or method type.

assignment

Apply this attribute to functions that overload a compound assignment operator. Functions that overload a compound assignment operator must mark their initial input parameter as inout. For an example of how to use the assignment attribute, see Compound Assignment Operators.

class_protocol

Apply this attribute to a protocol to indicate that the protocol can be adopted by class types only.

If you apply the objc attribute to a protocol, the class_protocol attribute is implicitly applied to that protocol; there’s no need to mark the protocol with the attribute explicitly.

exported

Apply this attribute to an import declaration to export the imported module, submodule, or declaration from the current module. If another module imports the current module, that other module can access the items exported by the current module.

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