Swift getting started tutorial 19-generic, swift getting started tutorial 19-
Original Blog, reprinted, please indicate the source
Blog.csdn.net/hello_hwc
Generic definition
Similar to C ++, generics define a reusable code that is applicable to any type and implements code in an abstract way. Both Array and Dictionary of Swift are implemented using generics, Because Array can save variables of the String type or Int type.
For example
func swapTwoInts(inout a: Int, inout b: Int) { let temporaryA = a a=b b = temporaryA}func swapTwoStrings(inout a: String, inout b: String) { let temporaryA = a a=b b = temporaryA}func swapTwoDoubles(inout a: Double, inout b: Double) { let temporaryA = a a=b b = temporaryA}
This is the same function structure used to exchange two types, but we have to define the corresponding function for each type without using generics. Very tedious.
After using generics, we only need to define
func swapTwoValues<T>(inout a: T, inout b: T) { let temporaryA = a a=b b = temporaryA}
Here T stands for the type, that is, it tells the compiler that it is a common type and will be replaced in actual computation. Type can be used as a parameter or return value. Of course, you can also define multiple, such as <T1, T2>
Note: Swift is a type-safe language. The Compiler checks the type and reports an error if the type does not match.
Type 2 Constraints
In generic definition, type constraints are very important. For example, if you define a generic type to sort a group of data, the data set must be comparable (greater than, equal to, less than). Otherwise, the incoming data set must contain Int, there are also strings, Int and String sorting, obviously there is no reasonable rule.
Generic constraints indicate that this type must inherit a class or implement certain protocols.
Syntax:
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) { // function body goes here}
Then, an example of defining generics using type constraints is implemented.
func findIndex<T: Equatable>(array: T[], valueToFind: T) -> Int? { for (index, value) in enumerate(array) { if value == valueToFind { return index } } return nil}
Here, a generic function is used to define a function to search for specified data in an array. Obviously, this type T must support the = Operator. Equatable is a system-provided protocol. You can use the = Operator to follow the protocol type.
Three Join types
In the second article, we used the Equatable provided by the system. How can we customize similar protocols?
The join type is used. The syntax is to use the typealise keyword in the protocol to define the join type.
Example
protocol Container {typealias ItemTypemutating func append(item: ItemType) var count: Int { get }subscript(i: Int) -> ItemType { get }}
Here, define an association type, ItemType. for the Protocol, any struct following this Protocol must implement two methods (append, count) and a subscript script. The specific type of ItemType is determined by the class that follows the protocol. For example
struct IntStack: Container {// IntStack
4. Where statement
The Where statement further limits the association type. A where statement allows a join type to comply with a specific protocol, or allows a specific data type to be consistent with that of the join type.
func allItemsMatch< C1: Container, C2: Container where C1.ItemType == C2.ItemType, C1.ItemType: Equatable> (someContainer: C1, anotherContainer: C2) -> Bool { if someContainer.count != anotherContainer.count { return false } for i in 0..<someContainer.count { if someContainer[i] != anotherContainer[i] { return false } } return true}
Four constraints are defined here.
1. C1 must follow the iner Protocol
2. C2 must follow the iner Protocol
3. The ItemType of C1 and C2 is consistent.
4. The ItemType of C1 follows the Equatable protocol.