This section covers generic types, generic functions, and parameters to generic constructors, including parameters and arguments. When you declare a generic type, function, or constructor, you specify the corresponding type parameters. The type parameter acts as a placeholder, which is replaced with a concrete type argument when a generic type is instantiated, a generic function is called, or a generic constructor is called.
For an overview of generics in the Swift language, see Generics (Part 2, Chapter 22).
Generic parameter statements
A generic parameter statement specifies the type parameters of a generic type or function and the associated constraints and requirements for those parameters. Generic parameter statements are enclosed in Angle brackets (<>) and have the following two forms:
1. <generic parameter list> <generic parameter list where requirements >
1. <generic parameter list> <generic parameter list where requirements >
Copy the code
The generic parameters in the generic parameter list are separated by commas, each of which takes the following form:
1. type parameter : constrain
Copy the code
A generic parameter consists of two parts: the type parameter and an optional constraint after it. Type parameters are just the names of placeholder types (such as T, U, V, KeyType, ValueType, etc.). You can use it in generic types, the rest of a function or constructor declaration, and in the signature of a function or constructor.
Constraints are used to indicate that the type parameter inherits from a class or adheres to a protocol or part of a protocol. For example, in the following generic type, the generic parameter T: Comparable means that any type argument used to replace the type parameter T must satisfy the Comparable protocol.
1. func simpleMin<T: COmparable>(x: T, y: T) -> T {
2. if x < y {
3. return y
4. }
5. return x
6. }
Copy the code
For example, if Int and Double satisfy the Comparable protocol, this function accepts either type. In contrast to generic types, there is no need to specify a generic argument statement when calling a generic function or constructor. Type arguments are inferred from arguments passed to a function or constructor.
1. SimpleMin (17, 42) 2. // what is inferred to be Int 3. SimpleMin (3.14159, 2.71828) 4Copy the code
Data Collection Office
Where clause
To specify additional requirements for type parameters and their associated types, you can add a WHERE statement after the generic parameter list. The WHERE statement consists of the keyword WHERE and its comma separated requirements.
The requirement in the WHERE statement is used to indicate that the type parameter inherits from a class or follows a protocol or part of a protocol. Although the WHERE statement helps to express simple constraints on a type parameter (such as T: Comparable equals T where T: Comparable, and so on), it can still be used to provide more complex constraints on a type parameter and its associated constraints. For example, <T where T: C, T: P> indicates that the generic type T inherits from class C and adheres to protocol P.
As mentioned above, you can force the association type of a constraint type parameter to comply with a protocol. <T: Generator where T.Element: Equatable> indicates that T complies with the Generator protocol, and that the association type of T, T.Element, complies with the Eauatable protocol (T has an association type because the Generator declares an Element, and T complies with the Generator protocol).
The operator == can also be used to specify the requirement that the two types are equivalent. For example, there is a constraint that T and U comply with the Generator protocol while requiring their association types to be equivalent, which can be expressed as: <T: Generator, U: Generator where t. Lement == U.lement >.
Of course, the type argument that replaces the type parameter must satisfy all the constraints and requirements required for the type parameter.
A generic function or constructor can be overloaded, but the type parameter in the generic parameter statement must have different constraints or requirements, or both. When an overloaded generic function or constructor is called, the compiler uses these constraints to determine which overloaded function or constructor to call.
A generic class can generate a subclass, but this subclass must also be generic.
Syntax for generic parameter clauses. PARAMETER clause →< generic-parameter-listrequirection – clause >. Generic-parameter-list → Generic PARAMETER LIST Generic parameter → type name. Generic parameter → Type name: Type identifier. Generic parameter Protocol type name: → Component type. Requirements- clause →WHERE? Requirements – the List? Requirements – the List – Requirements – Requirements, Requirements – the List. Requirements and Conformance to Requirements – the Same – Type – Requirements. Consistency – Requirements → Type – identifier: Type – identifier. Conformance – Required protocol type – Identifier: →- Combination – type. Same type requirement → Type identifier == Type identifier
Generic argument statements
The generic argument statement specifies the type argument of the generic type. Generic argument statements are enclosed in Angle brackets (<>) and have the following form:
1. < generic argument list >
Copy the code
The type arguments in the generic argument list are separated by commas. The type argument is the name of the actual concrete type used to replace the corresponding type parameter in the generic parameter statement of the generic type. This results in a specialized version of the generic type. For example, the Swift library’s generic dictionary type is defined as follows:
1. struct Dictionary<KeyTypel: Hashable, ValueType>: Collection, DictionaryLiteralConvertibl
e { /* .. */ }
Copy the code
A specialized version of the generic Dictionary type, Dictionary<String, Int>, is produced by replacing the generic types KeyType: Hashable and ValueType with concrete String and Int types. Each type argument must satisfy all the constraints of the generic parameter it replaces, including any additional requirements specified by the WHERE statement. In the example above, the type parameter KeyType is required to meet the Hashable protocol, so String must also meet the Hashable protocol.
You can replace a type parameter with a type argument that is itself a specialized version of a generic type (assuming the appropriate constraints and requirements are met). For example, to generate an Array whose element type is an integer Array, you can replace the type parameter T of the generic type Array with the specialized version of the Array, Array.
1. let arrayOfArrays: Array<Array<Int>> = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Copy the code
As described in the generic parameter statement, a generic argument statement cannot be used to specify type arguments to a generic function or constructor.
The syntax of a generic argument clause. Generic argument clause list <- generic – parameter – list ->→. Generic parameter list → Generic parameter Generic parameter, generic parameter list. Generic parameter → type
Data Collection Office
Due to the limited space of the article, I can only briefly introduce some current work achievements and thoughts, and there are some new directions to explore in each Swift. If you are interested in the underlying principles, architecture design, system construction and how to interview of iOS, you can also follow me to get the latest information and information related to the interview. If you have any comments and suggestions, welcome to leave me a message!
The bad place that writes welcomes everybody to point out, hope everybody leaves a message to discuss more, let us progress together!
Those who like iOS can pay attention to me and study together!!
included